Commit 651caa58 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5

into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
parents 8939a01d eb0ad91a
......@@ -12,7 +12,7 @@ NM := $(NM) -B
LDFLAGS_vmlinux = -static -N #-relax
CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8
ARCHBLOBLFLAGS := -I binary -O elf64-alpha -B alpha
LDFLAGS_BLOB := --format binary --oformat elf64-alpha
# Determine if we can use the BWX instructions with GAS.
old_gas := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; then echo y; else echo n; fi)
......
......@@ -69,7 +69,7 @@ SECTIONS
.init.ramfs ALIGN(8192): {
__initramfs_start = .;
*(.init.initramfs)
*(.init.ramfs)
__initramfs_end = .;
}
......
......@@ -337,7 +337,6 @@ config PREEMPT
config X86_UP_APIC
bool "Local APIC support on uniprocessors" if !SMP
default y if SMP
---help---
A local APIC (Advanced Programmable Interrupt Controller) is an
integrated interrupt controller in the CPU. If you have a single-CPU
......@@ -447,7 +446,7 @@ config X86_MCE
the 386 and 486, so nearly everyone can say Y here.
config X86_MCE_NONFATAL
bool "Check for non-fatal errors on Athlon/Duron"
bool "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
depends on X86_MCE
help
Enabling this feature starts a timer that triggers every 5 seconds which
......@@ -456,12 +455,12 @@ config X86_MCE_NONFATAL
Disable this if you don't want to see these messages.
Seeing the messages this option prints out may be indicative of dying hardware,
or out-of-spec (ie, overclocked) hardware.
This option only does something on hardware with Intel P6 style MCE.
(Pentium Pro and above, AMD Athlon/Duron)
This option only does something on certain CPUs.
(AMD Athlon/Duron and Intel Pentium 4)
config X86_MCE_P4THERMAL
bool "check for P4 thermal throttling interrupt."
depends on X86_MCE && X86_UP_APIC
depends on X86_MCE && (X86_UP_APIC || SMP)
help
Enabling this feature will cause a message to be printed when the P4
enters thermal throttling.
......
......@@ -42,7 +42,7 @@ cflags-$(CONFIG_MCRUSOE) += -march=i686 -malign-functions=0 -malign-jumps=0 -mal
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_MCYRIXIII) += $(call check_gcc,-march=c3,-march=i586)
cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-march=c3,-march=i486) -malign-functions=0 -malign-jumps=0 -malign-loops=0
CFLAGS += $(cflags-y)
......
......@@ -8,8 +8,7 @@ export-objs := mca.o i386_ksyms.o time.o
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o \
bootflag.o
pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o
obj-y += cpu/
obj-y += timers/
......
......@@ -13,7 +13,10 @@ obj-y += rise.o
obj-y += nexgen.o
obj-y += umc.o
obj-$(CONFIG_X86_MCE) += mcheck/
obj-$(CONFIG_MTRR) += mtrr/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
include $(TOPDIR)/Rules.make
......@@ -358,7 +358,9 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
boot_cpu_data.x86_capability[3]);
/* Init Machine Check Exception if available. */
#ifdef CONFIG_X86_MCE
mcheck_init(c);
#endif
}
/*
* Perform early boot up checks for a valid TSC. See arch/i386/kernel/time.c
......
......@@ -5,6 +5,7 @@
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/timer.h>
#include "cpu.h"
......@@ -170,7 +171,7 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
c->coma_bug = 1;
break;
case 4: /* MediaGX/GXm */
case 4: /* MediaGX/GXm or Geode GXM/GXLV/GX1 */
#ifdef CONFIG_PCI
/* It isn't really a PCI quirk directly, but the cure is the
same. The MediaGX has deep magic SMM stuff that handles the
......@@ -189,28 +190,25 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
#endif
c->x86_cache_size=16; /* Yep 16K integrated cache thats it */
/* GXm supports extended cpuid levels 'ala' AMD */
if (c->cpuid_level == 2) {
/* Enable Natsemi MMX extensions */
setCx86(CX86_CCR7, getCx86(CX86_CCR7) | 1);
get_model_name(c); /* get CPU marketing name */
/*
* The 5510/5520 companion chips have a funky PIT
* that breaks the TSC synchronizing, so turn it off
* The 5510/5520 companion chips have a funky PIT.
*/
if (pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) ||
pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL))
clear_bit(X86_FEATURE_TSC, c->x86_capability);
pit_latch_buggy = 1;
/* GXm supports extended cpuid levels 'ala' AMD */
if (c->cpuid_level == 2) {
/* Enable cxMMX extensions (GX1 Datasheet 54) */
setCx86(CX86_CCR7, getCx86(CX86_CCR7)|1);
get_model_name(c); /* get CPU marketing name */
return;
}
else { /* MediaGX */
Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';
p = Cx86_cb+2;
c->x86_model = (dir1 & 0x20) ? 1 : 2;
#ifndef CONFIG_CS5520
clear_bit(X86_FEATURE_TSC, c->x86_capability);
#endif
}
break;
......
obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o
obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o
include $(TOPDIR)/Rules.make
/*
* Athlon specific Machine Check Exception Reporting
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/msr.h>
#include "mce.h"
/* Machine Check Handler For AMD Athlon/Duron */
static void k7_machine_check(struct pt_regs * regs, long error_code)
{
int recover=1;
u32 alow, ahigh, high, low;
u32 mcgstl, mcgsth;
int i;
rdmsr (MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
if (mcgstl & (1<<0)) /* Recoverable ? */
recover=0;
printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
smp_processor_id(), mcgsth, mcgstl);
for (i=0; i<nr_mce_banks; i++) {
rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high);
if (high&(1<<31)) {
if (high & (1<<29))
recover |= 1;
if (high & (1<<25))
recover |= 2;
printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low);
high &= ~(1<<31);
if (high & (1<<27)) {
rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh);
printk ("[%08x%08x]", ahigh, alow);
}
if (high & (1<<26)) {
rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
printk (" at %08x%08x", ahigh, alow);
}
printk ("\n");
/* Clear it */
wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
/* Serialize */
wmb();
}
}
if (recover&2)
panic ("CPU context corrupt");
if (recover&1)
panic ("Unable to continue");
printk (KERN_EMERG "Attempting to continue.\n");
mcgstl &= ~(1<<2);
wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
}
/* AMD K7 machine check is Intel like */
void __init amd_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
int i;
machine_check_vector = k7_machine_check;
wmb();
printk (KERN_INFO "Intel machine check architecture supported.\n");
rdmsr (MSR_IA32_MCG_CAP, l, h);
if (l & (1<<8)) /* Control register present ? */
wrmsr (MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
nr_mce_banks = l & 0xff;
for (i=0; i<nr_mce_banks; i++) {
wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
}
set_in_cr4 (X86_CR4_MCE);
printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
smp_processor_id());
#ifdef CONFIG_X86_MCE_NONFATAL
init_nonfatal_mce_checker();
#endif
}
/*
* mce.c - x86 Machine Check Exception Reporting
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/smp.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/thread_info.h>
#include "mce.h"
int mce_disabled __initdata = 0;
int nr_mce_banks;
/* Handle unconfigured int18 (should never happen) */
static void unexpected_machine_check(struct pt_regs * regs, long error_code)
{
printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id());
}
/* Call the installed machine check handler for this CPU setup. */
void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
asmlinkage void do_machine_check(struct pt_regs * regs, long error_code)
{
machine_check_vector(regs, error_code);
}
/* This has to be run for each processor */
void __init mcheck_init(struct cpuinfo_x86 *c)
{
if (mce_disabled==1)
return;
switch (c->x86_vendor) {
case X86_VENDOR_AMD:
if (c->x86==6 || c->x86==15)
amd_mcheck_init(c);
break;
case X86_VENDOR_INTEL:
if (c->x86==5)
intel_p5_mcheck_init(c);
if (c->x86==6)
intel_p6_mcheck_init(c);
if (c->x86==15)
intel_p4_mcheck_init(c);
break;
case X86_VENDOR_CENTAUR:
if (c->x86==5)
winchip_mcheck_init(c);
break;
default:
break;
}
}
static int __init mcheck_disable(char *str)
{
mce_disabled = 1;
return 0;
}
static int __init mcheck_enable(char *str)
{
mce_disabled = -1;
return 0;
}
__setup("nomce", mcheck_disable);
__setup("mce", mcheck_enable);
#include <linux/init.h>
void amd_mcheck_init(struct cpuinfo_x86 *c);
void intel_p4_mcheck_init(struct cpuinfo_x86 *c);
void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
void intel_p6_mcheck_init(struct cpuinfo_x86 *c);
void winchip_mcheck_init(struct cpuinfo_x86 *c);
void init_nonfatal_mce_checker(void);
/* Call the installed machine check handler for this CPU setup. */
extern void (*machine_check_vector)(struct pt_regs *, long error_code);
extern int mce_disabled __initdata;
extern int nr_mce_banks;
/*
* P4 specific Machine Check Exception Reporting
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/config.h>
#include <linux/irq.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/msr.h>
#include "mce.h"
static struct timer_list mce_timer;
static int timerset;
#define MCE_RATE 15*HZ /* timer rate is 15s */
static void mce_checkregs (void *info)
{
u32 low, high;
int i;
preempt_disable();
for (i=0; i<nr_mce_banks; i++) {
rdmsr (MSR_IA32_MC0_STATUS+i*4, low, high);
if (high & (1<<31)) {
printk (KERN_EMERG "MCE: The hardware reports a non fatal, correctable incident occured on CPU %d.\n",
smp_processor_id());
printk (KERN_EMERG "Bank %d: %08x%08x\n", i, high, low);
/* Scrub the error so we don't pick it up in MCE_RATE seconds time. */
wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
/* Serialize */
wmb();
}
}
preempt_enable();
}
static void do_mce_timer(void *data)
{
mce_checkregs (NULL);
smp_call_function (mce_checkregs, NULL, 1, 1);
}
static DECLARE_WORK(mce_work, do_mce_timer, NULL);
static void mce_timerfunc (unsigned long data)
{
#ifdef CONFIG_SMP
if (num_online_cpus() > 1)
schedule_work (&mce_work);
#else
mce_checkregs (NULL);
#endif
mce_timer.expires = jiffies + MCE_RATE;
add_timer (&mce_timer);
}
void init_nonfatal_mce_checker()
{
if (timerset == 0) {
/* Set the timer to check for non-fatal
errors every MCE_RATE seconds */
init_timer (&mce_timer);
mce_timer.expires = jiffies + MCE_RATE;
mce_timer.data = 0;
mce_timer.function = &mce_timerfunc;
add_timer (&mce_timer);
timerset = 1;
printk(KERN_INFO "Machine check exception polling timer started.\n");
}
}
/*
* arch/i386/kernel/bluesmoke.c - x86 Machine Check Exception Reporting
* P4 specific Machine Check Exception Reporting
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/smp.h>
#include <linux/config.h>
#include <linux/irq.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/msr.h>
#include <asm/apic.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/hardirq.h>
#ifdef CONFIG_X86_MCE
#include "mce.h"
/* as supported by the P4/Xeon family */
struct intel_mce_extended_msrs {
......@@ -37,17 +32,16 @@ struct intel_mce_extended_msrs {
/* u32 *reserved[]; */
};
static int mce_disabled __initdata = 0;
static int mce_num_extended_msrs = 0;
static int banks;
#ifdef CONFIG_X86_MCE_P4THERMAL
/*
* P4/Xeon Thermal transition interrupt handler
*/
static void unexpected_thermal_interrupt(struct pt_regs *regs)
{
printk(KERN_ERR "CPU#%d: Unexpected LVT TMR interrupt!\n", smp_processor_id());
}
/* P4/Xeon Thermal transition interrupt handler */
static void intel_thermal_interrupt(struct pt_regs *regs)
{
u32 l, h;
......@@ -55,7 +49,7 @@ static void intel_thermal_interrupt(struct pt_regs *regs)
ack_APIC_irq();
rdmsr(MSR_IA32_THERM_STATUS, l, h);
rdmsr (MSR_IA32_THERM_STATUS, l, h);
if (l & 1) {
printk(KERN_EMERG "CPU#%d: Temperature above threshold\n", cpu);
printk(KERN_EMERG "CPU#%d: Running in modulated clock mode\n", cpu);
......@@ -64,15 +58,7 @@ static void intel_thermal_interrupt(struct pt_regs *regs)
}
}
static void unexpected_thermal_interrupt(struct pt_regs *regs)
{
printk(KERN_ERR "CPU#%d: Unexpected LVT TMR interrupt!\n", smp_processor_id());
}
/*
* Thermal interrupt handler for this CPU setup
*/
/* Thermal interrupt handler for this CPU setup */
static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt;
asmlinkage void smp_thermal_interrupt(struct pt_regs regs)
......@@ -83,7 +69,6 @@ asmlinkage void smp_thermal_interrupt(struct pt_regs regs)
}
/* P4/Xeon Thermal regulation detect and init */
static void __init intel_init_thermal(struct cpuinfo_x86 *c)
{
u32 l, h;
......@@ -101,7 +86,7 @@ static void __init intel_init_thermal(struct cpuinfo_x86 *c)
* be some SMM goo which handles it, so we can't even put a handler
* since it might be delivered via SMI already -zwanem.
*/
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
rdmsr (MSR_IA32_MISC_ENABLE, l, h);
h = apic_read(APIC_LVTTHMR);
if ((l & (1<<3)) && (h & APIC_DM_SMI)) {
printk(KERN_DEBUG "CPU#%d: Thermal monitoring handled by SMI\n", cpu);
......@@ -120,25 +105,24 @@ static void __init intel_init_thermal(struct cpuinfo_x86 *c)
h |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */
apic_write_around(APIC_LVTTHMR, h);
rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h);
rdmsr (MSR_IA32_THERM_INTERRUPT, l, h);
wrmsr (MSR_IA32_THERM_INTERRUPT, l | 0x03 , h);
/* ok we're good to go... */
vendor_thermal_interrupt = intel_thermal_interrupt;
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
rdmsr (MSR_IA32_MISC_ENABLE, l, h);
wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h);
l = apic_read(APIC_LVTTHMR);
apic_write_around(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
printk(KERN_INFO "CPU#%d: Thermal monitoring enabled\n", cpu);
l = apic_read (APIC_LVTTHMR);
apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
printk (KERN_INFO "CPU#%d: Thermal monitoring enabled\n", cpu);
return;
}
#endif /* CONFIG_X86_MCE_P4THERMAL */
/* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */
static int inline intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
{
u32 h;
......@@ -146,16 +130,16 @@ static int inline intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
if (mce_num_extended_msrs == 0)
goto done;
rdmsr(MSR_IA32_MCG_EAX, r->eax, h);
rdmsr(MSR_IA32_MCG_EBX, r->ebx, h);
rdmsr(MSR_IA32_MCG_ECX, r->ecx, h);
rdmsr(MSR_IA32_MCG_EDX, r->edx, h);
rdmsr(MSR_IA32_MCG_ESI, r->esi, h);
rdmsr(MSR_IA32_MCG_EDI, r->edi, h);
rdmsr(MSR_IA32_MCG_EBP, r->ebp, h);
rdmsr(MSR_IA32_MCG_ESP, r->esp, h);
rdmsr(MSR_IA32_MCG_EFLAGS, r->eflags, h);
rdmsr(MSR_IA32_MCG_EIP, r->eip, h);
rdmsr (MSR_IA32_MCG_EAX, r->eax, h);
rdmsr (MSR_IA32_MCG_EBX, r->ebx, h);
rdmsr (MSR_IA32_MCG_ECX, r->ecx, h);
rdmsr (MSR_IA32_MCG_EDX, r->edx, h);
rdmsr (MSR_IA32_MCG_ESI, r->esi, h);
rdmsr (MSR_IA32_MCG_EDI, r->edi, h);
rdmsr (MSR_IA32_MCG_EBP, r->ebp, h);
rdmsr (MSR_IA32_MCG_ESP, r->esp, h);
rdmsr (MSR_IA32_MCG_EFLAGS, r->eflags, h);
rdmsr (MSR_IA32_MCG_EIP, r->eip, h);
/* can we rely on kmalloc to do a dynamic
* allocation for the reserved registers?
......@@ -164,10 +148,6 @@ static int inline intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
return mce_num_extended_msrs;
}
/*
* Machine Check Handler For PII/PIII
*/
static void intel_machine_check(struct pt_regs * regs, long error_code)
{
int recover=1;
......@@ -176,329 +156,106 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
int i;
struct intel_mce_extended_msrs dbg;
rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
if(mcgstl&(1<<0)) /* Recoverable ? */
rdmsr (MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
if (mcgstl & (1<<0)) /* Recoverable ? */
recover=0;
printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl);
printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
smp_processor_id(), mcgsth, mcgstl);
if (intel_get_extended_msrs(&dbg)) {
printk(KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n",
printk (KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n",
smp_processor_id(), dbg.eip, dbg.eflags);
printk(KERN_DEBUG "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n",
printk (KERN_DEBUG "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n",
dbg.eax, dbg.ebx, dbg.ecx, dbg.edx);
printk(KERN_DEBUG "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n",
printk (KERN_DEBUG "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n",
dbg.esi, dbg.edi, dbg.ebp, dbg.esp);
}
for (i=0;i<banks;i++) {
rdmsr(MSR_IA32_MC0_STATUS+i*4,low, high);
if(high&(1<<31)) {
if(high&(1<<29))
recover|=1;
if(high&(1<<25))
recover|=2;
printk(KERN_EMERG "Bank %d: %08x%08x", i, high, low);
high&=~(1<<31);
if(high&(1<<27)) {
rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
printk("[%08x%08x]", ahigh, alow);
for (i=0; i<nr_mce_banks; i++) {
rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high);
if (high & (1<<31)) {
if (high & (1<<29))
recover |= 1;
if (high & (1<<25))
recover |= 2;
printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low);
high &= ~(1<<31);
if (high & (1<<27)) {
rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh);
printk ("[%08x%08x]", ahigh, alow);
}
if(high&(1<<26)) {
rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
printk(" at %08x%08x", ahigh, alow);
if (high & (1<<26)) {
rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
printk (" at %08x%08x", ahigh, alow);
}
printk("\n");
/* Clear it */
wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
/* Serialize */
wmb();
printk ("\n");
}
}
if(recover&2)
panic("CPU context corrupt");
if(recover&1)
panic("Unable to continue");
printk(KERN_EMERG "Attempting to continue.\n");
mcgstl&=~(1<<2);
wrmsr(MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
}
if (recover & 2)
panic ("CPU context corrupt");
if (recover & 1)
panic ("Unable to continue");
/*
* Machine check handler for Pentium class Intel
*/
static void pentium_machine_check(struct pt_regs * regs, long error_code)
{
u32 loaddr, hi, lotype;
rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
printk(KERN_EMERG "CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n", smp_processor_id(), loaddr, lotype);
if(lotype&(1<<5))
printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU on fire ?).\n", smp_processor_id());
}
/*
* Machine check handler for WinChip C6
*/
static void winchip_machine_check(struct pt_regs * regs, long error_code)
{
printk(KERN_EMERG "CPU#%d: Machine Check Exception.\n", smp_processor_id());
}
/*
* Handle unconfigured int18 (should never happen)
*/
static void unexpected_machine_check(struct pt_regs * regs, long error_code)
{
printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id());
}
/*
* Call the installed machine check handler for this CPU setup.
printk(KERN_EMERG "Attempting to continue.\n");
/*
* Do not clear the MSR_IA32_MCi_STATUS if the error is not
* recoverable/continuable.This will allow BIOS to look at the MSRs
* for errors if the OS could not log the error.
*/
static void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
asmlinkage void do_machine_check(struct pt_regs * regs, long error_code)
{
machine_check_vector(regs, error_code);
}
#ifdef CONFIG_X86_MCE_NONFATAL
static struct timer_list mce_timer;
static int timerset = 0;
#define MCE_RATE 15*HZ /* timer rate is 15s */
static void mce_checkregs (void *info)
{
u32 low, high;
int i;
preempt_disable();
for (i=0; i<banks; i++) {
rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
if ((low | high) != 0) {
printk (KERN_EMERG "MCE: The hardware reports a non fatal, correctable incident occured on CPU %d.\n", smp_processor_id());
printk (KERN_EMERG "Bank %d: %08x%08x\n", i, high, low);
/* Scrub the error so we don't pick it up in MCE_RATE seconds time. */
wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
for (i=0; i<nr_mce_banks; i++) {
u32 msr;
msr = MSR_IA32_MC0_STATUS+i*4;
rdmsr (msr, low, high);
if (high&(1<<31)) {
/* Clear it */
wrmsr(msr, 0UL, 0UL);
/* Serialize */
wmb();
}
}
preempt_enable();
}
static void do_mce_timer(void *data)
{
smp_call_function (mce_checkregs, NULL, 1, 1);
mcgstl &= ~(1<<2);
wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
}
static DECLARE_WORK(mce_work, do_mce_timer, NULL);
static void mce_timerfunc (unsigned long data)
{
#ifdef CONFIG_SMP
if (num_online_cpus() > 1)
schedule_work(&mce_work);
#else
mce_checkregs(NULL);
#endif
mce_timer.expires = jiffies + MCE_RATE;
add_timer (&mce_timer);
}
#endif
/*
* Set up machine check reporting for processors with Intel style MCE
*/
static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
int i;
static int done;
/*
* Check for MCE support
*/
if( !cpu_has(c, X86_FEATURE_MCE) )
return;
/*
* Pentium machine check
*/
if(c->x86 == 5)
{
/* Default P5 to off as its often misconnected */
if(mce_disabled != -1)
return;
machine_check_vector = pentium_machine_check;
wmb();
/* Read registers before enabling */
rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
if(done==0)
printk(KERN_INFO "Intel old style machine check architecture supported.\n");
/* Enable MCE */
set_in_cr4(X86_CR4_MCE);
printk(KERN_INFO "Intel old style machine check reporting enabled on CPU#%d.\n", smp_processor_id());
return;
}
/*
* Check for PPro style MCA
*/
if( !cpu_has(c, X86_FEATURE_MCA) )
return;
/* Ok machine check is available */
machine_check_vector = intel_machine_check;
wmb();
if(done==0)
printk(KERN_INFO "Intel machine check architecture supported.\n");
rdmsr(MSR_IA32_MCG_CAP, l, h);
if(l&(1<<8)) /* Control register present ? */
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
banks = l&0xff;
/* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
if (c->x86_vendor == X86_VENDOR_INTEL && c->x86 == 6) {
for(i=1; i<banks; i++)
wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
} else {
for(i=0; i<banks; i++)
wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
}
for(i=0; i<banks; i++)
wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
printk (KERN_INFO "Intel machine check architecture supported.\n");
rdmsr (MSR_IA32_MCG_CAP, l, h);
if (l & (1<<8)) /* Control register present ? */
wrmsr (MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
nr_mce_banks = l & 0xff;
set_in_cr4(X86_CR4_MCE);
printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
for (i=0; i<nr_mce_banks; i++) {
wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
}
/*
* Check for P4/Xeon specific MCE extensions
*/
set_in_cr4 (X86_CR4_MCE);
printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
smp_processor_id());
if (c->x86_vendor == X86_VENDOR_INTEL && c->x86 == 15) {
/* Check for P4/Xeon extended MCE MSRs */
rdmsr(MSR_IA32_MCG_CAP, l, h);
rdmsr (MSR_IA32_MCG_CAP, l, h);
if (l & (1<<9)) {/* MCG_EXT_P */
mce_num_extended_msrs = (l >> 16) & 0xff;
printk(KERN_INFO "CPU#%d: Intel P4/Xeon Extended MCE MSRs (%d) available\n",
printk (KERN_INFO "CPU#%d: Intel P4/Xeon Extended MCE MSRs (%d) available\n",
smp_processor_id(), mce_num_extended_msrs);
}
#ifdef CONFIG_X86_MCE_P4THERMAL
/* Check for P4/Xeon Thermal monitor */
intel_init_thermal(c);
#endif
}
done=1;
}
/*
* Set up machine check reporting on the Winchip C6 series
*/
static void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
{
u32 lo, hi;
/* Not supported on C3 */
if(c->x86 != 5)
return;
/* Winchip C6 */
machine_check_vector = winchip_machine_check;
wmb();
rdmsr(MSR_IDT_FCR1, lo, hi);
lo|= (1<<2); /* Enable EIERRINT (int 18 MCE) */
lo&= ~(1<<4); /* Enable MCE */
wrmsr(MSR_IDT_FCR1, lo, hi);
set_in_cr4(X86_CR4_MCE);
printk(KERN_INFO "Winchip machine check reporting enabled on CPU#%d.\n", smp_processor_id());
}
/*
* This has to be run for each processor
*/
void __init mcheck_init(struct cpuinfo_x86 *c)
{
if(mce_disabled==1)
return;
switch(c->x86_vendor)
{
case X86_VENDOR_AMD:
/* AMD K7 machine check is Intel like */
if(c->x86 == 6 || c->x86 == 15) {
intel_mcheck_init(c);
#ifdef CONFIG_X86_MCE_NONFATAL
if (timerset == 0) {
/* Set the timer to check for non-fatal
errors every MCE_RATE seconds */
init_timer (&mce_timer);
mce_timer.expires = jiffies + MCE_RATE;
mce_timer.data = 0;
mce_timer.function = &mce_timerfunc;
add_timer (&mce_timer);
timerset = 1;
printk(KERN_INFO "Machine check exception polling timer started.\n");
}
init_nonfatal_mce_checker();
#endif
}
break;
case X86_VENDOR_INTEL:
intel_mcheck_init(c);
break;
case X86_VENDOR_CENTAUR:
winchip_mcheck_init(c);
break;
default:
break;
}
}
static int __init mcheck_disable(char *str)
{
mce_disabled = 1;
return 0;
}
static int __init mcheck_enable(char *str)
{
mce_disabled = -1;
return 0;
}
__setup("nomce", mcheck_disable);
__setup("mce", mcheck_enable);
#else
asmlinkage void do_machine_check(struct pt_regs * regs, long error_code) {}
asmlinkage void smp_thermal_interrupt(struct pt_regs regs) {}
void __init mcheck_init(struct cpuinfo_x86 *c) {}
#endif
/*
* P5 specific Machine Check Exception Reporting
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/msr.h>
#include "mce.h"
/* Machine check handler for Pentium class Intel */
static void pentium_machine_check(struct pt_regs * regs, long error_code)
{
u32 loaddr, hi, lotype;
rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
printk(KERN_EMERG "CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n", smp_processor_id(), loaddr, lotype);
if(lotype&(1<<5))
printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU on fire ?).\n", smp_processor_id());
}
/* Set up machine check reporting for processors with Intel style MCE */
void __init intel_p5_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
/*Check for MCE support */
if( !cpu_has(c, X86_FEATURE_MCE) )
return;
/* Default P5 to off as its often misconnected */
if(mce_disabled != -1)
return;
machine_check_vector = pentium_machine_check;
wmb();
/* Read registers before enabling */
rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
printk(KERN_INFO "Intel old style machine check architecture supported.\n");
/* Enable MCE */
set_in_cr4(X86_CR4_MCE);
printk(KERN_INFO "Intel old style machine check reporting enabled on CPU#%d.\n", smp_processor_id());
}
/*
* P6 specific Machine Check Exception Reporting
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/msr.h>
#include "mce.h"
/* Machine Check Handler For PII/PIII */
static void intel_machine_check(struct pt_regs * regs, long error_code)
{
int recover=1;
u32 alow, ahigh, high, low;
u32 mcgstl, mcgsth;
int i;
rdmsr (MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
if (mcgstl & (1<<0)) /* Recoverable ? */
recover=0;
printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
smp_processor_id(), mcgsth, mcgstl);
for (i=0; i<nr_mce_banks; i++) {
rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high);
if (high & (1<<31)) {
if (high & (1<<29))
recover |= 1;
if (high & (1<<25))
recover |= 2;
printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low);
high &= ~(1<<31);
if (high & (1<<27)) {
rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh);
printk ("[%08x%08x]", ahigh, alow);
}
if (high & (1<<26)) {
rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
printk (" at %08x%08x", ahigh, alow);
}
printk ("\n");
}
}
if (recover & 2)
panic ("CPU context corrupt");
if (recover & 1)
panic ("Unable to continue");
printk (KERN_EMERG "Attempting to continue.\n");
/*
* Do not clear the MSR_IA32_MCi_STATUS if the error is not
* recoverable/continuable.This will allow BIOS to look at the MSRs
* for errors if the OS could not log the error.
*/
for (i=0; i<nr_mce_banks; i++) {
unsigned int msr;
msr = MSR_IA32_MC0_STATUS+i*4;
rdmsr (msr,low, high);
if (high & (1<<31)) {
/* Clear it */
wrmsr (msr, 0UL, 0UL);
/* Serialize */
wmb();
}
}
mcgstl &= ~(1<<2);
wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
}
/* Set up machine check reporting for processors with Intel style MCE */
void __init intel_p6_mcheck_init(struct cpuinfo_x86 *c)
{
u32 l, h;
int i;
/* Check for MCE support */
if (!cpu_has(c, X86_FEATURE_MCE))
return;
/* Check for PPro style MCA */
if (!cpu_has(c, X86_FEATURE_MCA))
return;
/* Ok machine check is available */
machine_check_vector = intel_machine_check;
wmb();
printk (KERN_INFO "Intel machine check architecture supported.\n");
rdmsr (MSR_IA32_MCG_CAP, l, h);
if (l & (1<<8)) /* Control register present ? */
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
nr_mce_banks = l & 0xff;
/* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
for (i=1; i<nr_mce_banks; i++) {
wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
}
set_in_cr4 (X86_CR4_MCE);
printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
smp_processor_id());
}
/*
* IDT Winchip specific Machine Check Exception Reporting
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/msr.h>
#include "mce.h"
/* Machine check handler for WinChip C6 */
static void winchip_machine_check(struct pt_regs * regs, long error_code)
{
printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
}
/* Set up machine check reporting on the Winchip C6 series */
void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
{
u32 lo, hi;
machine_check_vector = winchip_machine_check;
wmb();
rdmsr(MSR_IDT_FCR1, lo, hi);
lo|= (1<<2); /* Enable EIERRINT (int 18 MCE) */
lo&= ~(1<<4); /* Enable MCE */
wrmsr(MSR_IDT_FCR1, lo, hi);
set_in_cr4(X86_CR4_MCE);
printk(KERN_INFO "Winchip machine check reporting enabled on CPU#0.\n");
}
......@@ -471,10 +471,12 @@ ENTRY(page_fault)
pushl $do_page_fault
jmp error_code
#ifdef CONFIG_X86_MCE
ENTRY(machine_check)
pushl $0
pushl $do_machine_check
jmp error_code
#endif
ENTRY(spurious_interrupt_bug)
pushl $0
......
......@@ -61,6 +61,7 @@
#include <asm/arch_hooks.h>
extern spinlock_t i8259A_lock;
int pit_latch_buggy; /* extern */
#include "do_timer.h"
......
......@@ -60,6 +60,8 @@ static unsigned long get_offset_tsc(void)
static void mark_offset_tsc(void)
{
int count;
int countmp;
static int count1=0, count2=LATCH;
/*
* It is important that these two operations happen almost at
* the same time. We do the RDTSC stuff first, since it's
......@@ -83,6 +85,20 @@ static void mark_offset_tsc(void)
count |= inb(0x40) << 8;
spin_unlock(&i8253_lock);
if (pit_latch_buggy) {
/* get center value of last 3 time lutch */
if ((count2 >= count && count >= count1)
|| (count1 >= count && count >= count2)) {
count2 = count1; count1 = count;
} else if ((count1 >= count2 && count2 >= count)
|| (count >= count2 && count2 >= count1)) {
countmp = count;count = count2;
count2 = count1;count1 = countmp;
} else {
count2 = count1; count1 = count; count = count1;
}
}
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
}
......@@ -111,10 +127,12 @@ static unsigned long __init calibrate_tsc(void)
* Set the Gate high, program CTC channel 2 for mode 0,
* (interrupt on terminal count mode), binary count,
* load 5 * LATCH count, (LSB and MSB) to begin countdown.
*
* Some devices need a delay here.
*/
outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
outb_p(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
outb_p(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
{
unsigned long startlow, starthigh;
......@@ -238,8 +256,6 @@ static int init_tsc(void)
* moaned if you have the only one in the world - you fix it!
*/
dodgy_tsc();
if (cpu_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
if (tsc_quotient) {
......
......@@ -906,7 +906,9 @@ void __init trap_init(void)
set_trap_gate(15,&spurious_interrupt_bug);
set_trap_gate(16,&coprocessor_error);
set_trap_gate(17,&alignment_check);
#ifdef CONFIG_X86_MCE
set_trap_gate(18,&machine_check);
#endif
set_trap_gate(19,&simd_coprocessor_error);
set_system_gate(SYSCALL_VECTOR,&system_call);
......
......@@ -3139,12 +3139,12 @@ static int sbp2scsi_reset (Scsi_Cmnd *SCpnt)
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,44)
static int sbp2scsi_biosparam (struct scsi_device *sdev,
struct block_device *dev, sector_t capacy, int geom[])
struct block_device *dev, sector_t capacity, int geom[])
{
#else
static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[])
{
sector_t capacy = disk->capacity;
sector_t capacity = disk->capacity;
#endif
int heads, sectors, cylinders;
......
......@@ -549,10 +549,10 @@ static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id
static int sbp2scsi_detect (Scsi_Host_Template *tpnt);
static const char *sbp2scsi_info (struct Scsi_Host *host);
void sbp2scsi_setup(char *str, int *ints);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28)
static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,44)
static int sbp2scsi_biosparam (struct scsi_device *sdev, struct block_device *dev, sector_t capacity, int geom[]);
#else
static int sbp2scsi_biosparam (Scsi_Disk *disk, struct block_device *dev, int geom[]);
static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]);
#endif
static int sbp2scsi_abort (Scsi_Cmnd *SCpnt);
static int sbp2scsi_reset (Scsi_Cmnd *SCpnt);
......
......@@ -345,6 +345,51 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
}
}
/**
* NCR5380_poll_politely - wait for NCR5380 status bits
* @instance: controller to poll
* @reg: 5380 register to poll
* @bit: Bitmask to check
* @val: Value required to exit
*
* Polls the NCR5380 in a reasonably efficient manner waiting for
* an event to occur, after a short quick poll we begin giving the
* CPU back in non IRQ contexts
*
* Returns the value of the register or a negative error code.
*/
static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t)
{
NCR5380_local_declare();
int n = 500; /* At about 8uS a cycle for the cpu access */
unsigned long end = jiffies + t;
int r;
NCR5380_setup(instance);
while( n-- > 0)
{
r = NCR5380_read(reg);
if((r & bit) == val)
return r;
cpu_relax();
}
/* t time yet ? */
while(time_before(jiffies, end))
{
r = NCR5380_read(reg);
if((r & bit) == val)
return r;
if(!in_interrupt())
yield();
else
cpu_relax();
}
return -ETIMEDOUT;
}
static struct {
unsigned char value;
const char *name;
......@@ -679,7 +724,10 @@ static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
while (probe_irq == IRQ_NONE && time_before(jiffies, timeout))
barrier();
{
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
}
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
......@@ -1026,11 +1074,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
case 5:
printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
timeout = jiffies + 5 * HZ;
while (time_before(jiffies, timeout) && (NCR5380_read(STATUS_REG) & SR_BSY))
{
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
}
NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
break;
case 2:
printk(KERN_WARNING "scsi%d: bus busy, attempting abort\n", instance->host_no);
......@@ -1057,8 +1101,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
* twiddling done to the host specific fields of cmd. If the
* main coroutine is not running, it is restarted.
*
* Locks: host lock taken by caller. Called functions drop and
* retake this lock. Called functions take dma lock.
* Locks: host lock taken by caller
*/
static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
......@@ -1164,6 +1207,7 @@ static void NCR5380_main(void *p)
instance = hostdata->host;
if(instance->irq != IRQ_NONE)
spin_lock_irqsave(instance->host_lock, flags);
do {
......@@ -1243,12 +1287,9 @@ static void NCR5380_main(void *p)
do not respond to commands immediately
after a scan */
printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->target);
//spin_lock_irq(&io_request_lock);
LIST(tmp, hostdata->issue_queue);
tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
hostdata->issue_queue = tmp;
//spin_unlock_irq(&io_request_lock);
hostdata->time_expires = jiffies + USLEEP_WAITLONG;
NCR5380_set_timer(instance);
}
......@@ -1267,6 +1308,7 @@ static void NCR5380_main(void *p)
break;
} while (!done);
if(instance->irq != IRQ_NONE)
spin_unlock_irqrestore(instance->host_lock, flags);
}
......@@ -1341,24 +1383,9 @@ static void NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs)
hostdata->dmalen = 0;
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
#if NCR_TIMEOUT
{
unsigned long timeout = jiffies + NCR_TIMEOUT;
spin_unlock_irq(instance->host_lock);
/* FIXME: prove timer is always running here! */
while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK && time_before(jiffies, timeout))
cpu_relax();
spin_lock_irq(instance->host_lock);
if (time_after_eq(jiffies, timeout))
printk("scsi%d: timeout at NCR5380.c:%d\n", host->host_no, __LINE__);
}
#else /* NCR_TIMEOUT */
while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK)
cpu_relax();
#endif
/* FIXME: we need to poll briefly then defer a workqueue task ! */
NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ);
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
......@@ -1438,7 +1465,7 @@ static void collect_stats(struct NCR5380_hostdata *hostdata, Scsi_Cmnd * cmd)
* If failed (no target) : cmd->scsi_done() will be called, and the
* cmd->result host byte set to DID_BAD_TARGET.
*
* Locks: caller holds hostdata lock
* Locks: caller holds hostdata lock in IRQ mode
*/
static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
......@@ -1451,8 +1478,11 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
unsigned long timeout;
unsigned char value;
NCR5380_setup(instance);
int err;
if (hostdata->selecting) {
if(instance->irq != IRQ_NONE)
spin_unlock_irq(instance->host_lock);
goto part2; /* RvC: sorry prof. Dijkstra, but it keeps the
rest of the code nearly the same */
}
......@@ -1476,29 +1506,22 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(MODE_REG, MR_ARBITRATE);
/* Wait for arbitration logic to complete */
#if NCR_TIMEOUT
{
unsigned long timeout = jiffies + 2 * NCR_TIMEOUT;
if(instance->irq != IRQ_NONE)
spin_unlock_irq(instance->host_lock);
while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
&& time_before(jiffies, timeout))
cpu_relax();
/* We can be relaxed here, interrupts are on, we are
in workqueue context, the birds are singing in the trees */
err = NCR5380_poll_politely(instance, INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, ICR_ARBITRATION_PROGRESS, 5*HZ);
if(instance->irq != IRQ_NONE)
spin_lock_irq(instance->host_lock);
if (time_after_eq(jiffies, timeout)) {
printk("scsi: arbitration timeout at %d\n", __LINE__);
if (err < 0) {
printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__);
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
goto failed;
}
#else /* NCR_TIMEOUT */
while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS));
#endif
dprintk(NDEBUG_ARBITRATION, ("scsi%d : arbitration complete\n", instance->host_no));
......@@ -1515,7 +1538,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
NCR5380_write(MODE_REG, MR_BASE);
dprintk(NDEBUG_ARBITRATION, ("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no));
return -1;
goto failed;
}
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
......@@ -1528,7 +1551,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
dprintk(NDEBUG_ARBITRATION, ("scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no));
return -1;
goto failed;
}
/*
* Again, bus clear + bus settle time is 1.2us, however, this is
......@@ -1613,8 +1636,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
we poll only once ech clock tick */
value = NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO);
/* FIXME HZ=100 assumption ? */
if (!value && (hostdata->select_time < 25)) {
if (!value && (hostdata->select_time < HZ/4)) {
/* RvC: we still must wait for a device response */
hostdata->select_time++; /* after 25 ticks the device has failed */
hostdata->time_expires = jiffies + 1;
......@@ -1627,6 +1649,8 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
waiting period */
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
if(instance->irq != IRQ_NONE)
spin_lock_irq(instance->host_lock);
NCR5380_reselect(instance);
printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
......@@ -1645,13 +1669,15 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
if (hostdata->targets_present & (1 << cmd->target)) {
printk("scsi%d : weirdness\n", instance->host_no);
printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no);
if (hostdata->restart_select)
printk("\trestart select\n");
printk(KERN_DEBUG "\trestart select\n");
NCR5380_dprint(NDEBUG_SELECTION, instance);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
if(instance->irq != IRQ_NONE)
spin_lock_irq(instance->host_lock);
cmd->result = DID_BAD_TARGET << 16;
collect_stats(hostdata, cmd);
cmd->scsi_done(cmd);
......@@ -1678,29 +1704,21 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
*/
/* Wait for start of REQ/ACK handshake */
#ifdef NCR_TIMEOUT
{
unsigned long timeout = jiffies + NCR_TIMEOUT;
spin_unlock_irq(instance->host_lock);
while (!(NCR5380_read(STATUS_REG) & SR_REQ) && time_before(jiffies, timeout))
cpu_relax();
spin_lock_irq(instance->host_lock);
err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
if (time_after_eq(jiffies, timeout)) {
printk("scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
if(err)
{ printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
goto failed;
}
#else /* NCR_TIMEOUT */
while (!(NCR5380_read(STATUS_REG) & SR_REQ))
cpu_relax();
#endif /* def NCR_TIMEOUT */
dprintk(NDEBUG_SELECTION, ("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->target));
tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
if(instance->irq != IRQ_NONE)
spin_lock_irq(instance->host_lock);
len = 1;
cmd->tag = 0;
......@@ -1717,6 +1735,13 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
return 0;
/* Selection failed */
failed:
if(instance->irq != IRQ_NONE)
spin_lock_irq(instance->host_lock);
return -1;
}
/*
......@@ -1786,6 +1811,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
* if breaking is not allowed, we keep polling as long as needed
*/
/* FIXME */
while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) && !break_allowed);
if (!(tmp & SR_REQ)) {
/* timeout condition */
......@@ -1832,8 +1858,8 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
}
while (NCR5380_read(STATUS_REG) & SR_REQ);
/* FIXME - if this fails bus reset ?? */
NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ);
dprintk(NDEBUG_HANDSHAKE, ("scsi%d : req false, handshake complete\n", instance->host_no));
/*
......@@ -1905,8 +1931,9 @@ static void do_reset(struct Scsi_Host *host) {
static int do_abort(struct Scsi_Host *host) {
NCR5380_local_declare();
unsigned char tmp, *msgptr, phase;
unsigned char *msgptr, phase, tmp;
int len;
int rc;
NCR5380_setup(host);
......@@ -1923,15 +1950,21 @@ static int do_abort(struct Scsi_Host *host) {
* the target sees, so we just handshake.
*/
while (!(tmp = NCR5380_read(STATUS_REG)) & SR_REQ)
cpu_relax();
rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
if(rc < 0)
return -1;
tmp = (unsigned char)rc;
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
while (NCR5380_read(STATUS_REG) & SR_REQ);
rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, 0, 3*HZ);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
if(rc == -1)
return -1;
}
tmp = ABORT;
msgptr = &tmp;
......@@ -2245,7 +2278,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
* XXX Note : we need to watch for bus free or a reset condition here
* to recover from an unexpected bus free condition.
*
* Locks: io_request_lock held by caller
* Locks: io_request_lock held by caller in IRQ mode
*/
static void NCR5380_information_transfer(struct Scsi_Host *instance) {
......@@ -2503,7 +2536,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
/* Enable reselect interrupts */
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
/* Wait for bus free to avoid nasty timeouts */
/* Wait for bus free to avoid nasty timeouts - FIXME timeout !*/
/* NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */
while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
barrier();
return;
......@@ -2658,7 +2692,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
*
* Inputs : instance - this instance of the NCR5380.
*
* Locks: io_request_lock held by caller
* Locks: io_request_lock held by caller if IRQ driven
*/
static void NCR5380_reselect(struct Scsi_Host *instance) {
......@@ -2696,16 +2730,19 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
while (NCR5380_read(STATUS_REG) & SR_SEL);
/* FIXME: timeout too long, must fail to workqueue */
if(NCR5380_poll_politely(instance, STATUS_REG, SR_SEL, 0, 2*HZ)<0)
abort = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
/*
* Wait for target to go into MSGIN.
* FIXME: timeout needed
* FIXME: timeout needed and fail to work queeu
*/
while (!(NCR5380_read(STATUS_REG) & SR_REQ))
cpu_relax();
if(NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 2*HZ))
abort = 1;
len = 1;
data = msg;
......@@ -2713,7 +2750,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
NCR5380_transfer_pio(instance, &phase, &len, &data);
if (!msg[0] & 0x80) {
printk("scsi%d : expecting IDENTIFY message, got ", instance->host_no);
printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
print_msg(msg);
abort = 1;
} else {
......@@ -2747,7 +2784,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
break;
}
if (!tmp) {
printk("scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->host_no, target_mask, lun);
printk(KERN_ERR "scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->host_no, target_mask, lun);
/*
* Since we have an established nexus that we can't do anything with,
* we must abort it.
......@@ -2790,9 +2827,11 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) {
*
* We should use the Last Byte Sent bit, unfortunately this is
* not available on the 5380/5381 (only the various CMOS chips)
*
* FIXME: timeout, and need to handle long timeout/irq case
*/
while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ);
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
......@@ -2827,21 +2866,15 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) {
* a problem, we could implement longjmp() / setjmp(), setjmp()
* called where the loop started in NCR5380_main().
*
* Locks: host lock taken by function
* Locks: host lock taken by caller
*/
#ifndef NCR5380_abort
static
#endif
int NCR5380_abort(Scsi_Cmnd * cmd) {
static int NCR5380_abort(Scsi_Cmnd * cmd) {
NCR5380_local_declare();
struct Scsi_Host *instance = cmd->host;
unsigned long flags;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
Scsi_Cmnd *tmp, **prev;
spin_lock_irqsave(instance->host_lock, flags);
printk(KERN_WARNING "scsi%d : aborting command\n", instance->host_no);
print_Scsi_Cmnd(cmd);
......@@ -2884,7 +2917,6 @@ int NCR5380_abort(Scsi_Cmnd * cmd) {
* aborted flag and get back into our main loop.
*/
spin_unlock_irqrestore(instance->host_lock, flags);
return 0;
}
#endif
......@@ -2894,8 +2926,6 @@ int NCR5380_abort(Scsi_Cmnd * cmd) {
* from the issue queue.
*/
/* FIXME: check - I think we need the hostdata lock here */
/* KLL */
dprintk(NDEBUG_ABORT, ("scsi%d : abort going into loop.\n", instance->host_no));
for (prev = (Scsi_Cmnd **) & (hostdata->issue_queue), tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp = (Scsi_Cmnd *) tmp->host_scribble)
if (cmd == tmp) {
......@@ -2905,7 +2935,6 @@ int NCR5380_abort(Scsi_Cmnd * cmd) {
tmp->result = DID_ABORT << 16;
dprintk(NDEBUG_ABORT, ("scsi%d : abort removed command from issue queue.\n", instance->host_no));
tmp->done(tmp);
spin_unlock_irqrestore(instance->host_lock, flags);
return SUCCESS;
}
#if (NDEBUG & NDEBUG_ABORT)
......@@ -2927,7 +2956,6 @@ int NCR5380_abort(Scsi_Cmnd * cmd) {
if (hostdata->connected) {
dprintk(NDEBUG_ABORT, ("scsi%d : abort failed, command connected.\n", instance->host_no));
spin_unlock_irqrestore(instance->host_lock, flags);
return FAILED;
}
/*
......@@ -2972,7 +3000,6 @@ int NCR5380_abort(Scsi_Cmnd * cmd) {
tmp->host_scribble = NULL;
tmp->result = DID_ABORT << 16;
tmp->done(tmp);
spin_unlock_irqrestore(instance->host_lock, flags);
return SUCCESS;
}
}
......@@ -2985,7 +3012,6 @@ int NCR5380_abort(Scsi_Cmnd * cmd) {
* so we won't panic, but we will notify the user in case something really
* broke.
*/
spin_unlock_irqrestore(instance->host_lock, flags);
printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
" before abortion\n", instance->host_no);
return FAILED;
......@@ -2999,22 +3025,15 @@ int NCR5380_abort(Scsi_Cmnd * cmd) {
*
* Returns : SUCCESS
*
* Locks: host lock taken by function
* Locks: host lock taken by caller
*/
#ifndef NCR5380_bus_reset
static
#endif
int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
unsigned long flags;
struct Scsi_Host *instance = cmd->host;
static int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
NCR5380_local_declare();
NCR5380_setup(cmd->host);
spin_lock_irqsave(instance->host_lock, flags);
NCR5380_print_status(cmd->host);
do_reset(cmd->host);
spin_unlock_irqrestore(instance->host_lock, flags);
return SUCCESS;
}
......@@ -3028,12 +3047,7 @@ int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
* Locks: io_request_lock held by caller
*/
#ifndef NCR5380_device_reset
static
#endif
int NCR5380_device_reset(Scsi_Cmnd * cmd) {
NCR5380_local_declare();
NCR5380_setup(cmd->host);
static int NCR5380_device_reset(Scsi_Cmnd * cmd) {
return FAILED;
}
......@@ -3047,11 +3061,6 @@ int NCR5380_device_reset(Scsi_Cmnd * cmd) {
* Locks: io_request_lock held by caller
*/
#ifndef NCR5380_host_reset
static
#endif
int NCR5380_host_reset(Scsi_Cmnd * cmd) {
NCR5380_local_declare();
NCR5380_setup(cmd->host);
static int NCR5380_host_reset(Scsi_Cmnd * cmd) {
return FAILED;
}
......@@ -677,22 +677,6 @@ static void wait_intr(void)
NCR53c406a_intr(0, NULL, NULL);
}
static int NCR53c406a_command(Scsi_Cmnd * SCpnt)
{
DEB(printk("NCR53c406a_command called\n"));
NCR53c406a_queue(SCpnt, internal_done);
if (irq_level)
while (!internal_done_flag)
cpu_relax();
else /* interrupts not supported */
while (!internal_done_flag)
wait_intr();
internal_done_flag = 0;
return internal_done_errcode;
}
static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
{
int i;
......@@ -726,6 +710,21 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
return 0;
}
static int NCR53c406a_command(Scsi_Cmnd * SCpnt)
{
DEB(printk("NCR53c406a_command called\n"));
NCR53c406a_queue(SCpnt, internal_done);
if (irq_level)
while (!internal_done_flag)
cpu_relax();
else /* interrupts not supported */
while (!internal_done_flag)
wait_intr();
internal_done_flag = 0;
return internal_done_errcode;
}
static int NCR53c406a_abort(Scsi_Cmnd * SCpnt)
{
DEB(printk("NCR53c406a_abort called\n"));
......@@ -755,7 +754,7 @@ static int NCR53c406a_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
static int NCR53c406a_biosparm(struct scsi_disk *disk,
static int NCR53c406a_biosparm(struct scsi_device *disk,
struct block_device *dev,
sector_t capacity, int *info_array)
{
......@@ -1065,8 +1064,30 @@ static void __init calc_port_addr(void)
MODULE_LICENSE("GPL");
/* Eventually this will go into an include file, but this will be later */
static Scsi_Host_Template driver_template = NCR53c406a;
/* NOTE: scatter-gather support only works in PIO mode.
* Use SG_NONE if DMA mode is enabled!
*/
static Scsi_Host_Template driver_template =
{
proc_name: "NCR53c406a" /* proc_name */,
name: "NCR53c406a" /* name */,
detect: NCR53c406a_detect /* detect */,
info: NCR53c406a_info /* info */,
command: NCR53c406a_command /* command */,
queuecommand: NCR53c406a_queue /* queuecommand */,
eh_abort_handler: NCR53c406a_abort /* abort */,
eh_bus_reset_handler: NCR53c406a_bus_reset /* reset */,
eh_device_reset_handler: NCR53c406a_device_reset /* reset */,
eh_host_reset_handler: NCR53c406a_host_reset /* reset */,
bios_param: NCR53c406a_biosparm /* biosparm */,
can_queue: 1 /* can_queue */,
this_id: 7 /* SCSI ID of the chip */,
sg_tablesize: 32 /*SG_ALL*/ /*SG_NONE*/,
cmd_per_lun: 1 /* commands per lun */,
unchecked_isa_dma: 1 /* unchecked_isa_dma */,
use_clustering: ENABLE_CLUSTERING
};
#include "scsi_module.c"
......
#ifndef _NCR53C406A_H
#define _NCR53C406A_H
/*
* NCR53c406a.h
*
* Copyright (C) 1994 Normunds Saumanis (normunds@rx.tech.swh.lv)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*/
#ifndef NULL
#define NULL 0
#endif
/* NOTE: scatter-gather support only works in PIO mode.
* Use SG_NONE if DMA mode is enabled!
*/
#define NCR53c406a { \
proc_name: "NCR53c406a" /* proc_name */, \
name: "NCR53c406a" /* name */, \
detect: NCR53c406a_detect /* detect */, \
info: NCR53c406a_info /* info */, \
command: NCR53c406a_command /* command */, \
queuecommand: NCR53c406a_queue /* queuecommand */, \
eh_abort_handler: NCR53c406a_abort /* abort */, \
eh_bus_reset_handler: NCR53c406a_bus_reset /* reset */, \
eh_device_reset_handler: NCR53c406a_device_reset /* reset */, \
eh_host_reset_handler: NCR53c406a_host_reset /* reset */, \
bios_param: NCR53c406a_biosparm /* biosparm */, \
can_queue: 1 /* can_queue */, \
this_id: 7 /* SCSI ID of the chip */, \
sg_tablesize: 32 /*SG_ALL*/ /*SG_NONE*/, \
cmd_per_lun: 1 /* commands per lun */, \
unchecked_isa_dma: 1 /* unchecked_isa_dma */, \
use_clustering: ENABLE_CLUSTERING \
}
static int NCR53c406a_detect(Scsi_Host_Template *);
static const char *NCR53c406a_info(struct Scsi_Host *);
static int NCR53c406a_command(Scsi_Cmnd *);
static int NCR53c406a_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int NCR53c406a_abort(Scsi_Cmnd *);
static int NCR53c406a_bus_reset(Scsi_Cmnd *);
static int NCR53c406a_device_reset(Scsi_Cmnd *);
static int NCR53c406a_host_reset(Scsi_Cmnd *);
static int NCR53c406a_biosparm(Disk *, struct block_device *, sector_t, int[]);
#endif /* _NCR53C406A_H */
......@@ -20,6 +20,14 @@
*
* aha1740_makecode may still need even more work
* if it doesn't work for your devices, take a look.
*
* Reworked for new_eh and new locking by Alan Cox <alan@redhat.com>
*
* For the avoidance of doubt the "preferred form" of this code is one which
* is in an open non patent encumbered format. Where cryptographic key signing
* forms part of the process of creating an executable the information
* including keys needed to generate an equivalently functional executable
* are deemed to be part of the source code.
*/
#include <linux/module.h>
......@@ -68,7 +76,7 @@ static spinlock_t aha1740_lock = SPIN_LOCK_UNLOCKED;
/* One for each IRQ level (9-15) */
static struct Scsi_Host * aha_host[8] = {NULL, };
int aha1740_proc_info(char *buffer, char **start, off_t offset,
static int aha1740_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
{
int len;
......@@ -76,7 +84,7 @@ int aha1740_proc_info(char *buffer, char **start, off_t offset,
struct aha1740_hostdata *host;
if (inout)
return(-ENOSYS);
return-ENOSYS;
for (len = 0; len < 8; len++) {
shpnt = aha_host[len];
......@@ -103,7 +111,7 @@ int aha1740_proc_info(char *buffer, char **start, off_t offset,
}
int aha1740_makecode(unchar *sense, unchar *status)
static int aha1740_makecode(unchar *sense, unchar *status)
{
struct statusword
{
......@@ -179,7 +187,7 @@ int aha1740_makecode(unchar *sense, unchar *status)
return status[3] | retval << 16;
}
int aha1740_test_port(unsigned int base)
static int aha1740_test_port(unsigned int base)
{
char name[4], tmp;
......@@ -212,7 +220,7 @@ int aha1740_test_port(unsigned int base)
}
/* A "high" level interrupt handler */
void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
static void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
{
struct Scsi_Host *host = aha_host[irq - 9];
void (*my_done)(Scsi_Cmnd *);
......@@ -303,7 +311,7 @@ void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
spin_unlock_irqrestore(host->host_lock, flags);
}
int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
unchar direction;
unchar *cmd = (unchar *) SCpnt->cmnd;
......@@ -317,16 +325,6 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
if(*cmd == REQUEST_SENSE)
{
#if 0
/* scsi_request_sense() provides a buffer of size 256,
so there is no reason to expect equality */
if (bufflen != sizeof(SCpnt->sense_buffer))
{
printk("Wrong buffer length supplied for request sense (%d)\n",
bufflen);
}
#endif
SCpnt->result = 0;
done(SCpnt);
return 0;
......@@ -486,7 +484,7 @@ static void internal_done(Scsi_Cmnd * SCpnt)
SCpnt->SCp.Status++;
}
int aha1740_command(Scsi_Cmnd * SCpnt)
static int aha1740_command(Scsi_Cmnd * SCpnt)
{
aha1740_queuecommand(SCpnt, internal_done);
SCpnt->SCp.Status = 0;
......@@ -501,7 +499,7 @@ int aha1740_command(Scsi_Cmnd * SCpnt)
/* Query the board for its irq_level. Nothing else matters
in enhanced mode on an EISA bus. */
void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
static void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
unsigned int *translation)
{
static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
......@@ -511,7 +509,7 @@ void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
}
int aha1740_detect(Scsi_Host_Template * tpnt)
static int aha1740_detect(Scsi_Host_Template * tpnt)
{
int count = 0, slot;
......@@ -540,8 +538,8 @@ int aha1740_detect(Scsi_Host_Template * tpnt)
outb(G2CNTRL_HRST, G2CNTRL(slotbase));
outb(0, G2CNTRL(slotbase));
}
printk("Configuring aha174x at IO:%x, IRQ %d\n", slotbase, irq_level);
printk("aha174x: Extended translation %sabled.\n",
printk(KERN_INFO "Configuring aha174x at IO:%x, IRQ %d\n", slotbase, irq_level);
printk(KERN_INFO "aha174x: Extended translation %sabled.\n",
translation ? "en" : "dis");
DEB(printk("aha1740_detect: enable interrupt channel %d\n",irq_level));
if (request_irq(irq_level,aha1740_intr_handle,0,"aha1740",NULL)) {
......@@ -572,31 +570,7 @@ int aha1740_detect(Scsi_Host_Template * tpnt)
return count;
}
/* Note: They following two functions do not apply very well to the Adaptec,
which basically manages its own affairs quite well without our interference,
so I haven't put anything into them. I can faintly imagine someone with a
*very* badly behaved SCSI target (perhaps an old tape?) wanting the abort(),
but it hasn't happened yet, and doing aborts brings the Adaptec to its
knees. I cannot (at this moment in time) think of any reason to reset the
card once it's running. So there. */
int aha1740_abort(Scsi_Cmnd * SCpnt)
{
DEB(printk("aha1740_abort called\n"));
return SCSI_ABORT_SNOOZE;
}
/* We do not implement a reset function here, but the upper level code assumes
that it will get some kind of response for the command in SCpnt. We must
oblige, or the command will hang the scsi system */
int aha1740_reset(Scsi_Cmnd * SCpnt, unsigned int ignored)
{
DEB(printk("aha1740_reset called\n"));
return SCSI_RESET_PUNT;
}
int aha1740_biosparam(struct scsi_device *sdev, struct block_device *dev,
static int aha1740_biosparam(struct scsi_device *sdev, struct block_device *dev,
sector_t capacity, int* ip)
{
int size = capacity;
......
......@@ -14,7 +14,7 @@
/* Eisa Enhanced mode operation - slot locating and addressing */
#define MINEISA 1 /* I don't have an EISA Spec to know these ranges, so I */
#define MAXEISA 8 /* Just took my machine's specifications. Adjust to fit.*/
#define MAXEISA 8 /* Just took my machine's specifications. Adjust to fit. */
/* I just saw an ad, and bumped this from 6 to 8 */
#define SLOTBASE(x) ((x << 12) + 0xc80)
#define SLOTSIZE 0x5c
......@@ -124,7 +124,7 @@ struct ecb { /* Enhanced Control Block 6.1 */
dir:1, /* Direction of transfer 1 = datain */
st:1, /* Suppress Transfer */
chk:1, /* Calculate Checksum */
:2, rec:1, :1; /* Error Recovery */
:2, rec:1,:1; /* Error Recovery */
u16 nil0; /* nothing */
u32 dataptr; /* Data or Scatter List ptr */
u32 datalen; /* Data or Scatter List len */
......@@ -140,7 +140,7 @@ struct ecb { /* Enhanced Control Block 6.1 */
u8 sense[MAX_SENSE]; /* Sense area */
u8 status[MAX_STATUS]; /* Status area */
Scsi_Cmnd *SCpnt; /* Link to the SCSI Command Block */
void (*done)(Scsi_Cmnd *); /* Completion Function */
void (*done) (Scsi_Cmnd *); /* Completion Function */
};
#define AHA1740CMD_NOP 0x00 /* No OP */
......@@ -152,32 +152,22 @@ struct ecb { /* Enhanced Control Block 6.1 */
#define AHA1740CMD_RINQ 0x0a /* Read Host Adapter Inquiry Data */
#define AHA1740CMD_TARG 0x10 /* Target SCSI Command */
int aha1740_detect(Scsi_Host_Template *);
int aha1740_command(Scsi_Cmnd *);
int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int aha1740_abort(Scsi_Cmnd *);
int aha1740_reset(Scsi_Cmnd *, unsigned int);
int aha1740_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
int aha1740_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout);
static int aha1740_detect(Scsi_Host_Template *);
static int aha1740_command(Scsi_Cmnd *);
static int aha1740_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int aha1740_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
static int aha1740_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
#define AHA1740_ECBS 32
#define AHA1740_SCATTER 16
#define AHA1740_CMDLUN 1
#ifndef NULL
#define NULL 0
#endif
#define AHA1740 { proc_name: "aha1740", \
proc_info: aha1740_proc_info, \
name: "Adaptec 174x (EISA)", \
detect: aha1740_detect, \
command: aha1740_command, \
queuecommand: aha1740_queuecommand, \
abort: aha1740_abort, \
reset: aha1740_reset, \
bios_param: aha1740_biosparam, \
can_queue: AHA1740_ECBS, \
this_id: 7, \
......
......@@ -476,7 +476,6 @@ MODULE_AUTHOR("Dario Ballabio");
#include <linux/blk.h>
#include "scsi.h"
#include "hosts.h"
#include "sd.h"
#include <asm/dma.h>
#include <asm/irq.h>
#include "eata.h"
......@@ -1838,7 +1837,7 @@ int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *dkinfo) {
int size = capacity;
if (ext_tran || (scsicam_bios_param(disk, bdev, dkinfo) < 0)) {
if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
dkinfo[0] = 255;
dkinfo[1] = 63;
dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
......
......@@ -18,8 +18,6 @@ static int eata2x_slave_attach(Scsi_Device *);
detect: eata2x_detect, \
release: eata2x_release, \
queuecommand: eata2x_queuecommand, \
abort: NULL, \
reset: NULL, \
eh_abort_handler: eata2x_eh_abort, \
eh_device_reset_handler: NULL, \
eh_bus_reset_handler: NULL, \
......
......@@ -14,6 +14,9 @@
* neuffer@goofy.zdv.uni-mainz.de *
* a.arnold@kfa-juelich.de *
* *
* Updated 2002 by Alan Cox <alan@redhat.com> for Linux *
* 2.5.x and the newer locking and error handling *
* *
* 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 *
......@@ -31,8 +34,16 @@
* the Free Software Foundation, Inc., 675 Mass Ave, *
* Cambridge, MA 02139, USA. *
* *
* For the avoidance of doubt the "preferred form" of this *
* code is one which is in an open non patent encumbered *
* format. Where cryptographic key signing forms part of *
* the process of creating an executable the information *
* including keys needed to generate an equivalently *
* functional executable are deemed to be part of the *
* source code are deemed to be part of the source code. *
* *
************************************************************
* last change: 96/07/16 OS: Linux 2.0.8 *
* last change: 2002/11/02 OS: Linux 2.5.45 *
************************************************************/
/* Look in eata_pio.h for configuration information */
......@@ -57,56 +68,60 @@
#include <linux/blk.h>
#include <linux/spinlock.h>
static uint ISAbases[MAXISA] =
{0x1F0, 0x170, 0x330, 0x230};
static uint ISAirqs[MAXISA] =
{14,12,15,11};
static unchar EISAbases[] =
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
static uint ISAbases[MAXISA] = {
0x1F0, 0x170, 0x330, 0x230
};
static uint ISAirqs[MAXISA] = {
14, 12, 15, 11
};
static unsigned char EISAbases[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
};
static uint registered_HBAs = 0;
static struct Scsi_Host *last_HBA = NULL;
static struct Scsi_Host *first_HBA = NULL;
static unchar reg_IRQ[] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static unchar reg_IRQL[] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static struct Scsi_Host *last_HBA;
static struct Scsi_Host *first_HBA;
static unsigned char reg_IRQ[];
static unsigned char reg_IRQL[];
static ulong int_counter = 0;
static ulong queue_counter = 0;
static unsigned long int_counter = 0;
static unsigned long queue_counter = 0;
#include "eata_pio_proc.c"
#ifdef MODULE
int eata_pio_release(struct Scsi_Host *sh)
static int eata_pio_release(struct Scsi_Host *sh)
{
if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL);
else reg_IRQ[sh->irq]--;
if (sh->irq && reg_IRQ[sh->irq] == 1)
free_irq(sh->irq, NULL);
else
reg_IRQ[sh->irq]--;
if (SD(sh)->channel == 0) {
if (sh->io_port && sh->n_io_port)
release_region(sh->io_port, sh->n_io_port);
}
return(TRUE);
return (TRUE);
}
#endif
void IncStat(Scsi_Pointer *SCp, uint Increment)
static void IncStat(Scsi_Pointer * SCp, uint Increment)
{
SCp->ptr+=Increment;
if ((SCp->this_residual-=Increment)==0)
{
if ((--SCp->buffers_residual)==0) SCp->Status=FALSE;
else
{
SCp->ptr += Increment;
if ((SCp->this_residual -= Increment) == 0) {
if ((--SCp->buffers_residual) == 0)
SCp->Status = FALSE;
else {
SCp->buffer++;
SCp->ptr=page_address(SCp->buffer->page) + SCp->buffer->offset;
SCp->this_residual=SCp->buffer->length;
SCp->ptr = page_address(SCp->buffer->page) + SCp->buffer->offset;
SCp->this_residual = SCp->buffer->length;
}
}
}
void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs);
static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs);
void do_eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs)
static void do_eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long flags;
struct Scsi_Host *dev = dev_id;
......@@ -116,128 +131,120 @@ void do_eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs)
spin_unlock_irqrestore(dev->host_lock, flags);
}
void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs)
static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
uint eata_stat = 0xfffff;
Scsi_Cmnd *cmd;
hostdata *hd;
struct eata_ccb *cp;
uint base;
uint x,z;
uint x, z;
struct Scsi_Host *sh;
ushort zwickel=0;
unchar stat,odd;
unsigned short zwickel = 0;
unsigned char stat, odd;
for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) {
for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev)
{
if (sh->irq != irq)
continue;
if (inb((uint)sh->base + HA_RSTATUS) & HA_SBUSY)
if (inb((uint) sh->base + HA_RSTATUS) & HA_SBUSY)
continue;
int_counter++;
hd=SD(sh);
hd = SD(sh);
cp = &hd->ccb[0];
cmd = cp->cmd;
base = (uint) cmd->host->base;
do
{
stat=inb(base+HA_RSTATUS);
if (stat&HA_SDRQ) {
if (cp->DataIn)
{
z=256; odd=FALSE;
while ((cmd->SCp.Status)&&((z>0)||(odd)))
{
if (odd)
{
*(cmd->SCp.ptr)=zwickel>>8;
IncStat(&cmd->SCp,1);
odd=FALSE;
}
x=min_t(unsigned int,z,cmd->SCp.this_residual/2);
insw(base+HA_RDATA,cmd->SCp.ptr,x);
z-=x;
IncStat(&cmd->SCp,2*x);
if ((z>0)&&(cmd->SCp.this_residual==1))
{
zwickel=inw(base+HA_RDATA);
*(cmd->SCp.ptr)=zwickel&0xff;
IncStat(&cmd->SCp,1); z--;
odd=TRUE;
do {
stat = inb(base + HA_RSTATUS);
if (stat & HA_SDRQ) {
if (cp->DataIn) {
z = 256;
odd = FALSE;
while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
if (odd) {
*(cmd->SCp.ptr) = zwickel >> 8;
IncStat(&cmd->SCp, 1);
odd = FALSE;
}
x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
insw(base + HA_RDATA, cmd->SCp.ptr, x);
z -= x;
IncStat(&cmd->SCp, 2 * x);
if ((z > 0) && (cmd->SCp.this_residual == 1)) {
zwickel = inw(base + HA_RDATA);
*(cmd->SCp.ptr) = zwickel & 0xff;
IncStat(&cmd->SCp, 1);
z--;
odd = TRUE;
}
}
while (z>0) {
zwickel=inw(base+HA_RDATA);
while (z > 0) {
zwickel = inw(base + HA_RDATA);
z--;
}
}
else /* cp->DataOut */
{
odd=FALSE; z=256;
while ((cmd->SCp.Status)&&((z>0)||(odd)))
{
if (odd)
{
zwickel+=*(cmd->SCp.ptr)<<8;
IncStat(&cmd->SCp,1);
outw(zwickel,base+HA_RDATA);
} else { /* cp->DataOut */
odd = FALSE;
z = 256;
while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
if (odd) {
zwickel += *(cmd->SCp.ptr) << 8;
IncStat(&cmd->SCp, 1);
outw(zwickel, base + HA_RDATA);
z--;
odd=FALSE;
odd = FALSE;
}
x=min_t(unsigned int,z,cmd->SCp.this_residual/2);
outsw(base+HA_RDATA,cmd->SCp.ptr,x);
z-=x;
IncStat(&cmd->SCp,2*x);
if ((z>0)&&(cmd->SCp.this_residual==1))
{
zwickel=*(cmd->SCp.ptr);
zwickel&=0xff;
IncStat(&cmd->SCp,1);
odd=TRUE;
x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
outsw(base + HA_RDATA, cmd->SCp.ptr, x);
z -= x;
IncStat(&cmd->SCp, 2 * x);
if ((z > 0) && (cmd->SCp.this_residual == 1)) {
zwickel = *(cmd->SCp.ptr);
zwickel &= 0xff;
IncStat(&cmd->SCp, 1);
odd = TRUE;
}
}
while (z>0||odd) {
outw(zwickel,base+HA_RDATA);
while (z > 0 || odd) {
outw(zwickel, base + HA_RDATA);
z--;
odd=FALSE;
odd = FALSE;
}
}
}
}
while ((stat&HA_SDRQ)||((stat&HA_SMORE)&&hd->moresupport));
while ((stat & HA_SDRQ) || ((stat & HA_SMORE) && hd->moresupport));
/* terminate handler if HBA goes busy again, i.e. transfers
* more data */
if (stat&HA_SBUSY) break;
if (stat & HA_SBUSY)
break;
/* OK, this is quite stupid, but I haven't found any correct
* way to get HBA&SCSI status so far */
if (!(inb(base+HA_RSTATUS)&HA_SERROR))
{
cmd->result=(DID_OK<<16);
hd->devflags|=(1<<cp->cp_id);
}
else if (hd->devflags&1<<cp->cp_id)
cmd->result=(DID_OK<<16)+0x02;
else cmd->result=(DID_NO_CONNECT<<16);
if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {
cmd->result = (DID_OK << 16);
hd->devflags |= (1 << cp->cp_id);
} else if (hd->devflags & 1 << cp->cp_id)
cmd->result = (DID_OK << 16) + 0x02;
else
cmd->result = (DID_NO_CONNECT << 16);
if (cp->status == LOCKED) {
cp->status = FREE;
eata_stat = inb(base + HA_RSTATUS);
printk(KERN_CRIT "eata_pio: int_handler, freeing locked "
"queueslot\n");
printk(KERN_CRIT "eata_pio: int_handler, freeing locked " "queueslot\n");
return;
}
#if DBG_INTR2
if (stat != 0x50)
printk(KERN_DEBUG "stat: %#.2x, result: %#.8x\n", stat,
cmd->result);
printk(KERN_DEBUG "stat: %#.2x, result: %#.8x\n", stat, cmd->result);
#endif
cp->status = FREE; /* now we can release the slot */
......@@ -248,25 +255,25 @@ void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs)
return;
}
inline uint eata_pio_send_command(uint base, unchar command)
static inline uint eata_pio_send_command(uint base, unsigned char command)
{
uint loop = HZ/2;
uint loop = HZ / 2;
while (inb(base + HA_RSTATUS) & HA_SBUSY)
if (--loop == 0)
return(TRUE);
return (TRUE);
/* Enable interrupts for HBA. It is not the best way to do it at this
* place, but I hope that it doesn't interfere with the IDE driver
* initialization this way */
outb(HA_CTRL_8HEADS,base+HA_CTRLREG);
outb(HA_CTRL_8HEADS, base + HA_CTRLREG);
outb(command, base + HA_WCOMMAND);
return(FALSE);
return (FALSE);
}
int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
static int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{
uint x, y;
uint base;
......@@ -285,13 +292,11 @@ int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
y = x = 0;
if (hd->ccb[y].status!=FREE) {
if (hd->ccb[y].status != FREE) {
DBG(DBG_QUEUE, printk(KERN_EMERG "can_queue %d, x %d, y %d\n",
sh->can_queue,x,y));
DBG(DBG_QUEUE, printk(KERN_EMERG "can_queue %d, x %d, y %d\n", sh->can_queue, x, y));
#if DEBUG_EATA
panic(KERN_EMERG "eata_pio: run out of queue slots cmdno:%ld "
"intrno: %ld\n", queue_counter, int_counter);
panic(KERN_EMERG "eata_pio: run out of queue slots cmdno:%ld " "intrno: %ld\n", queue_counter, int_counter);
#else
panic(KERN_EMERG "eata_pio: run out of queue slots....\n");
#endif
......@@ -304,33 +309,17 @@ int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
cp->status = USED; /* claim free slot */
DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:"
" %x, y %d\n", cmd->pid, cmd->target, cmd->lun, y));
cmd->scsi_done = (void *)done;
/* FIXME: use passed direction flag !! */
switch (cmd->cmnd[0]) {
case CHANGE_DEFINITION: case COMPARE: case COPY:
case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT:
case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER:
case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
case WRITE_6: case WRITE_10: case WRITE_VERIFY:
case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME:
case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12:
case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW:
case MEDIUM_SCAN: case SEND_VOLUME_TAG:
case 0xea: /* alternate number for WRITE LONG */
DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" " %x, y %d\n", cmd->pid, cmd->target, cmd->lun, y));
cmd->scsi_done = (void *) done;
if(cmd->sc_data_direction == SCSI_DATA_WRITE)
cp->DataOut = TRUE; /* Output mode */
break;
case TEST_UNIT_READY:
default:
else
cp->DataIn = TRUE; /* Input mode */
}
cp->Interpret = (cmd->target == hd->hostid);
cp->cp_datalen = htonl((ulong)cmd->request_bufflen);
cp->cp_datalen = htonl((unsigned long) cmd->request_bufflen);
cp->Auto_Req_Sen = FALSE;
cp->cp_reqDMA = htonl(0);
cp->reqlen = 0;
......@@ -345,11 +334,10 @@ int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
cp->cp_viraddr = cp;
cp->cmd = cmd;
cmd->host_scribble = (char *)&hd->ccb[y];
cmd->host_scribble = (char *) &hd->ccb[y];
if (cmd->use_sg == 0)
{
cmd->SCp.buffers_residual=1;
if (cmd->use_sg == 0) {
cmd->SCp.buffers_residual = 1;
cmd->SCp.ptr = cmd->request_buffer;
cmd->SCp.this_residual = cmd->request_bufflen;
cmd->SCp.buffer = NULL;
......@@ -362,86 +350,70 @@ int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
cmd->SCp.Status = (cmd->SCp.this_residual != 0); /* TRUE as long as bytes
* are to transfer */
if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP))
{
if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) {
cmd->result = DID_BUS_BUSY << 16;
printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, "
"returning DID_BUS_BUSY, done.\n", cmd->target, cmd->pid);
printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " "returning DID_BUS_BUSY, done.\n", cmd->target, cmd->pid);
done(cmd);
cp->status = FREE;
return (0);
}
/* FIXME: timeout */
while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
cpu_relax();
outsw(base + HA_RDATA, cp, hd->cplen);
outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
for (x = 0; x < hd->cppadlen; x++) outw(0, base + HA_RDATA);
for (x = 0; x < hd->cppadlen; x++)
outw(0, base + HA_RDATA);
DBG(DBG_QUEUE,printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x "
"lun: %x slot %d irq %d\n", (long)sh->base, cmd->pid,
cmd->target, cmd->lun, y, sh->irq));
DBG(DBG_QUEUE, printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " "lun: %x slot %d irq %d\n", (long) sh->base, cmd->pid, cmd->target, cmd->lun, y, sh->irq));
return (0);
}
int eata_pio_abort(Scsi_Cmnd * cmd)
static int eata_pio_abort(Scsi_Cmnd * cmd)
{
ulong flags;
uint loop = HZ;
spin_lock_irqsave(cmd->host->host_lock, flags);
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld "
"target: %x lun: %x reason %x\n", cmd->pid,
cmd->target, cmd->lun, cmd->abort_reason));
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x reason %x\n", cmd->pid, cmd->target, cmd->lun, cmd->abort_reason));
while (inb((uint)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY)
while (inb(cmd->host->base + HA_RAUXSTAT) & HA_ABUSY)
if (--loop == 0) {
printk(KERN_WARNING "eata_pio: abort, timeout error.\n");
spin_unlock_irqrestore(cmd->host->host_lock, flags);
return (SCSI_ABORT_ERROR);
return FAILED;
}
if (CD(cmd)->status == FREE) {
DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_NOT_RUNNING\n"));
spin_unlock_irqrestore(cmd->host->host_lock, flags);
return (SCSI_ABORT_NOT_RUNNING);
return FAILED;
}
if (CD(cmd)->status == USED) {
DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_BUSY\n"));
spin_unlock_irqrestore(cmd->host->host_lock, flags);
return (SCSI_ABORT_BUSY); /* SNOOZE */
/* We want to sleep a bit more here */
return FAILED; /* SNOOZE */
}
if (CD(cmd)->status == RESET) {
spin_unlock_irqrestore(cmd->host->host_lock, flags);
printk(KERN_WARNING "eata_pio: abort, command reset error.\n");
return (SCSI_ABORT_ERROR);
return FAILED;
}
if (CD(cmd)->status == LOCKED) {
spin_unlock_irqrestore(cmd->host->host_lock, flags);
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio: abort, queue slot "
"locked.\n"));
return (SCSI_ABORT_NOT_RUNNING);
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio: abort, queue slot " "locked.\n"));
return FAILED;
}
spin_unlock_irqrestore(cmd->host->host_lock, flags);
panic("eata_pio: abort: invalid slot status\n");
}
int eata_pio_reset(Scsi_Cmnd * cmd, unsigned int dummy)
static int eata_pio_host_reset(Scsi_Cmnd * cmd)
{
uint x, limit = 0;
ulong flags;
unchar success = FALSE;
unsigned char success = FALSE;
Scsi_Cmnd *sp;
struct Scsi_Host *host = cmd->host;
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:"
" %x lun: %x reason %x\n", cmd->pid, cmd->target,
cmd->lun, cmd->abort_reason));
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->target, cmd->lun, cmd->abort_reason));
spin_lock_irqsave(cmd->host->host_lock, flags);
if (HD(cmd)->state == RESET) {
printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
spin_unlock_irqrestore(cmd->host->host_lock, flags);
return (SCSI_RESET_ERROR);
return FAILED;
}
/* force all slots to be free */
......@@ -453,24 +425,24 @@ int eata_pio_reset(Scsi_Cmnd * cmd, unsigned int dummy)
sp = HD(cmd)->ccb[x].cmd;
HD(cmd)->ccb[x].status = RESET;
printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x,
sp->pid);
printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->pid);
if (sp == NULL)
panic("eata_pio_reset: slot %d, sp==NULL.\n", x);
}
/* hard reset the HBA */
outb(EATA_CMD_RESET, (uint) cmd->host->base+HA_WCOMMAND);
outb(EATA_CMD_RESET, (uint) cmd->host->base + HA_WCOMMAND);
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n"));
HD(cmd)->state = RESET;
spin_unlock_irq(host->host_lock);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(3*HZ);
schedule_timeout(3 * HZ);
spin_lock_irq(host->host_lock);
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, "
"loops %d.\n", limit));
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " "loops %d.\n", limit));
for (x = 0; x < cmd->host->can_queue; x++) {
......@@ -482,25 +454,24 @@ int eata_pio_reset(Scsi_Cmnd * cmd, unsigned int dummy)
sp->result = DID_RESET << 16;
/* This mailbox is terminated */
printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n",x);
printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n", x);
HD(cmd)->ccb[x].status = FREE;
sp->scsi_done(sp);
}
HD(cmd)->state = FALSE;
spin_unlock_irqrestore(cmd->host->host_lock, flags);
if (success) { /* hmmm... */
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
return (SCSI_RESET_SUCCESS);
return SUCCESS;
} else {
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, wakeup.\n"));
return (SCSI_RESET_PUNT);
return FAILED;
}
}
char * get_pio_board_data(ulong base, uint irq, uint id, ulong cplen, ushort cppadlen)
static char *get_pio_board_data(unsigned long base, uint irq, uint id, unsigned long cplen, unsigned short cppadlen)
{
struct eata_ccb cp;
static char buff[256];
......@@ -530,28 +501,29 @@ char * get_pio_board_data(ulong base, uint irq, uint id, ulong cplen, ushort cpp
while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
outsw(base + HA_RDATA, &cp, cplen);
outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
for (z = 0; z < cppadlen; z++) outw(0, base + HA_RDATA);
for (z = 0; z < cppadlen; z++)
outw(0, base + HA_RDATA);
while (inb(base + HA_RSTATUS) & HA_SBUSY);
if (inb(base + HA_RSTATUS) & HA_SERROR)
return (NULL);
else if (!(inb(base + HA_RSTATUS) & HA_SDRQ))
return (NULL);
else
{
insw(base+HA_RDATA, &buff, 127);
while (inb(base + HA_RSTATUS)&HA_SDRQ) inw(base + HA_RDATA);
else {
insw(base + HA_RDATA, &buff, 127);
while (inb(base + HA_RSTATUS) & HA_SDRQ)
inw(base + HA_RDATA);
return (buff);
}
}
int get_pio_conf_PIO(u32 base, struct get_conf *buf)
static int get_pio_conf_PIO(u32 base, struct get_conf *buf)
{
ulong loop = HZ/2;
unsigned long loop = HZ / 2;
int z;
ushort *p;
unsigned short *p;
if(check_region(base, 9))
if (check_region(base, 9))
return (FALSE);
memset(buf, 0, sizeof(struct get_conf));
......@@ -560,29 +532,25 @@ int get_pio_conf_PIO(u32 base, struct get_conf *buf)
if (--loop == 0)
return (FALSE);
DBG(DBG_PIO && DBG_PROBE,
printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base));
DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base));
eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG);
loop = HZ/2;
for (p = (ushort *) buf;
(long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) {
loop = HZ / 2;
for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) {
while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
if (--loop == 0)
return (FALSE);
loop = HZ/2;
loop = HZ / 2;
*p = inw(base + HA_RDATA);
}
if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */
if (htonl(EATA_SIGNATURE) == buf->signature) {
DBG(DBG_PIO&&DBG_PROBE, printk(KERN_NOTICE "EATA Controller found "
"at %#4x EATA Level: %x\n", base,
(uint) (buf->version)));
DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " "at %#4x EATA Level: %x\n", base, (uint) (buf->version)));
while (inb(base + HA_RSTATUS) & HA_SDRQ)
inw(base + HA_RDATA);
if(ALLOW_DMA_BOARDS == FALSE) {
if (ALLOW_DMA_BOARDS == FALSE) {
for (z = 0; z < MAXISA; z++)
if (base == ISAbases[z]) {
buf->IRQ = ISAirqs[z];
......@@ -592,29 +560,22 @@ int get_pio_conf_PIO(u32 base, struct get_conf *buf)
return (TRUE);
}
} else {
DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer "
"for HBA at %x\n", base));
DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " "for HBA at %x\n", base));
}
return (FALSE);
}
void print_pio_config(struct get_conf *gc)
static void print_pio_config(struct get_conf *gc)
{
printk("Please check values: (read config data)\n");
printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n",
(uint) ntohl(gc->len), gc->version,
gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support);
printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n",
gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2],
gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND);
printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n",
gc->IRQ, gc->IRQ_TR, gc->FORCADR,
gc->MAX_CHAN, gc->ID_qest);
printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n", (uint) ntohl(gc->len), gc->version, gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support);
printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n", gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2], gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND);
printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n", gc->IRQ, gc->IRQ_TR, gc->FORCADR, gc->MAX_CHAN, gc->ID_qest);
}
static uint print_selftest(uint base)
{
unchar buffer[512];
unsigned char buffer[512];
#ifdef VERBOSE_SETUP
int z;
#endif
......@@ -625,49 +586,44 @@ static uint print_selftest(uint base)
do {
while (inb(base + HA_RSTATUS) & HA_SBUSY)
/* nothing */ ;
if (inb(base + HA_RSTATUS) & HA_SDRQ)
{
if (inb(base + HA_RSTATUS) & HA_SDRQ) {
insw(base + HA_RDATA, &buffer, 256);
#ifdef VERBOSE_SETUP
/* no beeps please... */
for (z = 0; z < 511 && buffer[z]; z++)
if (buffer[z] != 7) printk("%c", buffer[z]);
if (buffer[z] != 7)
printk("%c", buffer[z]);
#endif
}
} while (inb(base+HA_RSTATUS) & (HA_SBUSY|HA_SDRQ));
} while (inb(base + HA_RSTATUS) & (HA_SBUSY | HA_SDRQ));
return (!(inb(base+HA_RSTATUS) & HA_SERROR));
return (!(inb(base + HA_RSTATUS) & HA_SERROR));
}
int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
{
ulong size = 0;
unsigned long size = 0;
char *buff;
ulong cplen;
ushort cppadlen;
unsigned long cplen;
unsigned short cppadlen;
struct Scsi_Host *sh;
hostdata *hd;
DBG(DBG_REGISTER, print_pio_config(gc));
if (gc->DMA_support == TRUE) {
printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n",base);
if(ALLOW_DMA_BOARDS == FALSE)
printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n", base);
if (ALLOW_DMA_BOARDS == FALSE)
return (FALSE);
}
if ((buff = get_pio_board_data((uint)base, gc->IRQ, gc->scsi_id[3],
cplen =(htonl(gc->cplen )+1)/2,
cppadlen=(htons(gc->cppadlen)+1)/2)) == NULL)
{
printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (ulong) base);
if ((buff = get_pio_board_data((uint) base, gc->IRQ, gc->scsi_id[3], cplen = (htonl(gc->cplen) + 1) / 2, cppadlen = (htons(gc->cppadlen) + 1) / 2)) == NULL) {
printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (unsigned long) base);
return (FALSE);
}
if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE)
{
printk("HBA at %#lx failed while performing self test & setup.\n",
(ulong) base);
if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE) {
printk("HBA at %#lx failed while performing self test & setup.\n", (unsigned long) base);
return (FALSE);
}
......@@ -676,15 +632,13 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
sh = scsi_register(tpnt, size);
if(sh == NULL)
{
if (sh == NULL) {
release_region(base, 8);
return FALSE;
}
if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */
if (!request_irq(gc->IRQ, do_eata_pio_int_handler, SA_INTERRUPT,
"EATA-PIO", sh)){
if (!request_irq(gc->IRQ, do_eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", sh)) {
reg_IRQ[gc->IRQ]++;
if (!gc->IRQ_TR)
reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */
......@@ -695,8 +649,7 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
}
} else { /* More than one HBA on this IRQ */
if (reg_IRQL[gc->IRQ] == TRUE) {
printk("Can't support more than one HBA on this IRQ,\n"
" if the IRQ is edge triggered. Sorry.\n");
printk("Can't support more than one HBA on this IRQ,\n" " if the IRQ is edge triggered. Sorry.\n");
release_region(base, 8);
return (FALSE);
} else
......@@ -706,7 +659,7 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
hd = SD(sh);
memset(hd->ccb, 0, (sizeof(struct eata_ccb) * ntohs(gc->queuesiz)));
memset(hd->reads, 0, sizeof(ulong) * 26);
memset(hd->reads, 0, sizeof(unsigned long) * 26);
strncpy(SD(sh)->vendor, &buff[8], 8);
SD(sh)->vendor[8] = 0;
......@@ -735,7 +688,7 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
SD(sh)->EATA_revision = '?';
}
if(ntohl(gc->len) >= 0x22) {
if (ntohl(gc->len) >= 0x22) {
if (gc->is_PCI == TRUE)
hd->bustype = IS_PCI;
else if (gc->is_EISA == TRUE)
......@@ -751,11 +704,11 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
hd->bustype = IS_ISA;
}
SD(sh)->cplen=cplen;
SD(sh)->cppadlen=cppadlen;
SD(sh)->hostid=gc->scsi_id[3];
SD(sh)->devflags=1<<gc->scsi_id[3];
SD(sh)->moresupport=gc->MORE_support;
SD(sh)->cplen = cplen;
SD(sh)->cppadlen = cppadlen;
SD(sh)->hostid = gc->scsi_id[3];
SD(sh)->devflags = 1 << gc->scsi_id[3];
SD(sh)->moresupport = gc->MORE_support;
sh->unique_id = base;
sh->base = base;
sh->io_port = base;
......@@ -781,7 +734,7 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
hd->next = NULL; /* build a linked list of all HBAs */
hd->prev = last_HBA;
if(hd->prev != NULL)
if (hd->prev != NULL)
SD(hd->prev)->next = sh;
last_HBA = sh;
if (first_HBA == NULL)
......@@ -790,13 +743,13 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
return (1);
}
void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
static void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
{
int i;
for (i = 0; i < MAXISA; i++) {
if (ISAbases[i]) {
if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE){
if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE) {
register_pio_HBA(ISAbases[i], buf, tpnt);
}
ISAbases[i] = 0;
......@@ -805,7 +758,7 @@ void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
return;
}
void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
static void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
{
u32 base;
int i;
......@@ -819,24 +772,19 @@ void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
base = 0x1c88 + (i * 0x1000);
#if CHECKPAL
pal1 = inb((u16)base - 8);
pal2 = inb((u16)base - 7);
pal3 = inb((u16)base - 6);
if (((pal1 == 0x12) && (pal2 == 0x14)) ||
((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) ||
((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: "
"%x %x %x \n",
(int)pal1, (int)pal2, (int)pal3));
pal1 = inb((u16) base - 8);
pal2 = inb((u16) base - 7);
pal3 = inb((u16) base - 6);
if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3));
#endif
if (get_pio_conf_PIO(base, buf) == TRUE) {
DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf));
if (buf->IRQ) {
register_pio_HBA(base, buf, tpnt);
} else
printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA "
"removed from list\n");
printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n");
}
/* Nothing found here so we take it from the list */
EISAbases[i] = 0;
......@@ -848,7 +796,7 @@ void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
return;
}
void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
{
#ifndef CONFIG_PCI
printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
......@@ -857,8 +805,7 @@ void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
u32 base, x;
while ((dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) {
DBG(DBG_PROBE && DBG_PCI,
printk("eata_pio: find_PCI, HBA at %s\n", dev->name));
DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", dev->name));
if (pci_enable_device(dev))
continue;
pci_set_master(dev);
......@@ -899,8 +846,7 @@ void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
}
#if CHECK_BLINK
else if (check_blink_state(base) == TRUE) {
printk("eata_pio: HBA is in BLINK state.\n"
"Consult your HBAs manual to correct this.\n");
printk("eata_pio: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n");
}
#endif
}
......@@ -909,7 +855,7 @@ void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
}
int eata_pio_detect(Scsi_Host_Template * tpnt)
static int eata_pio_detect(Scsi_Host_Template * tpnt)
{
struct Scsi_Host *HBA_ptr;
struct get_conf gc;
......@@ -931,24 +877,17 @@ int eata_pio_detect(Scsi_Host_Template * tpnt)
if (registered_HBAs != 0) {
printk("EATA (Extended Attachment) PIO driver version: %d.%d%s\n"
"(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n"
" Alfred Arnold, a.arnold@kfa-juelich.de\n"
"This release only supports DASD devices (harddisks)\n",
VER_MAJOR, VER_MINOR, VER_SUB);
"(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n" " Alfred Arnold, a.arnold@kfa-juelich.de\n" "This release only supports DASD devices (harddisks)\n", VER_MAJOR, VER_MINOR, VER_SUB);
printk("Registered HBAs:\n");
printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:"
" QS: SG: CPL:\n");
printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:" " QS: SG: CPL:\n");
for (i = 1; i <= registered_HBAs; i++) {
printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d %d %d %c"
" %2d %2d %2d\n",
HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')?
"PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
(uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel,
HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N',
HBA_ptr->can_queue, HBA_ptr->sg_tablesize,
HBA_ptr->cmd_per_lun);
SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P') ?
"PCI " : (SD(HBA_ptr)->bustype == 'E') ? "EISA" : "ISA ",
(uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE) ? 'Y' : 'N', HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
HBA_ptr = SD(HBA_ptr)->next;
}
}
......
......@@ -2,7 +2,7 @@
* Header file for eata_pio.c Linux EATA-PIO SCSI driver *
* (c) 1993-96 Michael Neuffer *
*********************************************************
* last change: 96/05/05 *
* last change: 2002/11/02 *
********************************************************/
......@@ -14,7 +14,6 @@
#include "hosts.h"
#include <scsi/scsicam.h>
#ifndef HOSTS_C
#include "eata_generic.h"
#define VER_MAJOR 0
......@@ -58,49 +57,22 @@
#define DBG(x, y)
#endif
#endif /* !HOSTS_C */
int eata_pio_detect(Scsi_Host_Template *);
const char *eata_pio_info(struct Scsi_Host *);
int eata_pio_command(Scsi_Cmnd *);
int eata_pio_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int eata_pio_abort(Scsi_Cmnd *);
int eata_pio_reset(Scsi_Cmnd *, unsigned int);
int eata_pio_proc_info(char *, char **, off_t, int, int, int);
#ifdef MODULE
int eata_pio_release(struct Scsi_Host *);
#else
#define eata_pio_release NULL
#endif
static int eata_pio_detect(Scsi_Host_Template *);
static int eata_pio_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int eata_pio_abort(Scsi_Cmnd *);
static int eata_pio_host_reset(Scsi_Cmnd *);
static int eata_pio_proc_info(char *, char **, off_t, int, int, int);
static int eata_pio_release(struct Scsi_Host *);
#define EATA_PIO { \
proc_info: eata_pio_proc_info, /* procinfo */ \
name: "EATA (Extended Attachment) PIO driver", \
name: "EATA (Extended Attachment) PIO driver",\
detect: eata_pio_detect, \
release: eata_pio_release, \
queuecommand: eata_pio_queue, \
abort: eata_pio_abort, \
reset: eata_pio_reset, \
unchecked_isa_dma: 1, /* True if ISA */ \
use_clustering: ENABLE_CLUSTERING }
eh_abort_handler: eata_pio_abort, \
eh_host_reset_handler: eata_pio_host_reset, \
use_clustering: ENABLE_CLUSTERING \
}
#endif /* _EATA_PIO_H */
/*
* Overrides for Emacs so that we almost follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* tab-width: 8
* End:
*/
......@@ -1325,13 +1325,13 @@ static int fd_mcs_host_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) {
static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt)
{
return FAILED;
}
}
static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
struct Scsi_Host *shpnt = SCpnt->host;
unsigned long flags;
#if DEBUG_RESET
static int called_once = 0;
......@@ -1348,8 +1348,6 @@ static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) {
called_once = 1;
#endif
spin_lock_irqsave(shpnt->host_lock, flags);
outb(1, SCSI_Cntl_port);
do_pause(2);
outb(0, SCSI_Cntl_port);
......@@ -1360,15 +1358,14 @@ static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) {
/* Unless this is the very first call (i.e., SCPnt == NULL), everything
is probably hosed at this point. We will, however, try to keep
things going by informing the high-level code that we need help. */
spin_unlock_irqrestore(shpnt->host_lock, flags);
return SUCCESS;
}
}
#include <scsi/scsi_ioctl.h>
static int fd_mcs_biosparam(Scsi_Disk * disk, struct block_device *bdev,
sector_t capacity, int *info_array) {
static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev,
sector_t capacity, int *info_array)
{
unsigned char buf[512 + sizeof(int) * 2];
int size = capacity;
int *sizes = (int *) buf;
......@@ -1382,11 +1379,10 @@ static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) {
sizes[0] = 0; /* zero bytes out */
sizes[1] = 512; /* one sector in */
memcpy(data, do_read, sizeof(do_read));
retcode = kernel_scsi_ioctl(disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf);
retcode = kernel_scsi_ioctl(disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf);
if (!retcode /* SCSI command ok */
&& data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
&& data[0x1c2]) { /* Partition type */
/* The partition table layout is as follows:
Start: 0x1b3h
......@@ -1419,12 +1415,11 @@ static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) {
info_array[0] = data[0x1c3] + 1; /* heads */
info_array[1] = data[0x1c4] & 0x3f; /* sectors */
} else {
/* Note that this new method guarantees that there will always be
less than 1024 cylinders on a platter. This is good for drives
up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
if ((unsigned int) size >= 0x7e0000U) {
if ((unsigned int) size >= 0x7e0000U)
{
info_array[0] = 0xff; /* heads = 255 */
info_array[1] = 0x3f; /* sectors = 63 */
} else if ((unsigned int) size >= 0x200000U) {
......@@ -1437,6 +1432,8 @@ static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) {
}
/* For both methods, compute the cylinders */
info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
return 0;
}
/* Eventually this will go into an include file, but this will be later */
static Scsi_Host_Template driver_template = FD_MCS;
......
......@@ -30,7 +30,7 @@ static int fd_mcs_bus_reset(Scsi_Cmnd *);
static int fd_mcs_device_reset(Scsi_Cmnd *);
static int fd_mcs_host_reset(Scsi_Cmnd *);
static int fd_mcs_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int fd_mcs_biosparam(Disk *, struct block_device *,
static int fd_mcs_biosparam(struct scsi_device *, struct block_device *,
sector_t, int *);
static int fd_mcs_proc_info(char *, char **, off_t, int, int, int);
static const char *fd_mcs_info(struct Scsi_Host *);
......
......@@ -54,7 +54,7 @@ static int generic_NCR5380_device_reset(Scsi_Cmnd *);
static int notyet_generic_proc_info (char *buffer ,char **start, off_t offset,
int length, int hostno, int inout);
static const char* generic_NCR5380_info(struct Scsi_Host *);
static int generic_NCR5380_biosparam(Disk *, struct block_device *, sector_t, int *);
static int generic_NCR5380_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
static int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout);
#ifndef CMD_PER_LUN
......
......@@ -192,7 +192,7 @@ typedef struct SHT
/*
* Old EH handlers, no longer used. Make them warn the user of old
* drivers by using a wrogn type
* drivers by using a wrong type
*/
int (*abort)(int);
int (*reset)(int,int);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -10,18 +10,14 @@
/* Common forward declarations for all Linux-versions: */
/* Interfaces to the midlevel Linux SCSI driver */
extern int ibmmca_proc_info (char *, char **, off_t, int, int, int);
extern int ibmmca_detect (Scsi_Host_Template *);
extern int ibmmca_release (struct Scsi_Host *);
extern int ibmmca_command (Scsi_Cmnd *);
extern int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
extern int ibmmca_abort (Scsi_Cmnd *);
extern int ibmmca_reset (Scsi_Cmnd *, unsigned int);
extern int ibmmca_biosparam (struct scsi_device *, struct block_device *,
sector_t, int *);
/*structure for /proc filesystem */
extern struct proc_dir_entry proc_scsi_ibmmca;
static int ibmmca_proc_info (char *, char **, off_t, int, int, int);
static int ibmmca_detect (Scsi_Host_Template *);
static int ibmmca_release (struct Scsi_Host *);
static int ibmmca_command (Scsi_Cmnd *);
static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int ibmmca_abort (Scsi_Cmnd *);
static int ibmmca_host_reset (Scsi_Cmnd *);
static int ibmmca_biosparam (struct scsi_device *, struct block_device *, sector_t, int *);
/*
* 2/8/98
......@@ -37,8 +33,8 @@ extern struct proc_dir_entry proc_scsi_ibmmca;
release: ibmmca_release, /*release fn*/ \
command: ibmmca_command, /*command fn*/ \
queuecommand: ibmmca_queuecommand, /*queuecommand fn*/ \
abort: ibmmca_abort, /*abort fn*/ \
reset: ibmmca_reset, /*reset fn*/ \
eh_abort_handler:ibmmca_abort, /*abort fn*/ \
eh_host_reset_handler:ibmmca_host_reset, /*reset fn*/ \
bios_param: ibmmca_biosparam, /*bios fn*/ \
can_queue: 16, /*can_queue*/ \
this_id: 7, /*set by detect*/ \
......
......@@ -16,6 +16,11 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For the avoidance of doubt the "preferred form" of this code is one which
* is in an open non patent encumbered format. Where cryptographic key signing
* forms part of the process of creating an executable the information
* including keys needed to generate an equivalently functional executable
* are deemed to be part of the source code.
*
* Drew Eckhardt's excellent 'Generic NCR5380' sources provided
* much of the inspiration and some of the code for this driver.
......@@ -102,6 +107,10 @@
* this thing into as good a shape as possible, and I'm positive
* there are lots of lurking bugs and "Stupid Places".
*
* Updated for Linux 2.5 by Alan Cox <alan@redhat.com>
* - Using new_eh handler
* - Hopefully got all the locking right again
* See "FIXME" notes for items that could do with more work
*/
#include <linux/module.h>
......@@ -121,8 +130,8 @@
#include "scsi.h"
#include "hosts.h"
#define IN2000_VERSION "1.33"
#define IN2000_DATE "26/August/1998"
#define IN2000_VERSION "1.33-2.5"
#define IN2000_DATE "2002/11/03"
#include "in2000.h"
......@@ -174,8 +183,7 @@
*/
/* Normally, no defaults are specified... */
static char *setup_args[] =
{"","","","","","","","",""};
static char *setup_args[] = { "", "", "", "", "", "", "", "", "" };
/* filled in by 'insmod' */
static char *setup_strings = 0;
......@@ -184,14 +192,9 @@ static char *setup_strings = 0;
MODULE_PARM(setup_strings, "s");
#endif
static struct Scsi_Host *instance_list = 0;
static inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num)
{
write1_io(reg_num,IO_WD_ADDR);
write1_io(reg_num, IO_WD_ADDR);
return read1_io(IO_WD_DATA);
}
......@@ -201,8 +204,8 @@ static inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num)
static inline void write_3393(struct IN2000_hostdata *hostdata, uchar reg_num, uchar value)
{
write1_io(reg_num,IO_WD_ADDR);
write1_io(value,IO_WD_DATA);
write1_io(reg_num, IO_WD_ADDR);
write1_io(value, IO_WD_DATA);
}
......@@ -210,21 +213,21 @@ static inline void write_3393_cmd(struct IN2000_hostdata *hostdata, uchar cmd)
{
/* while (READ_AUX_STAT() & ASR_CIP)
printk("|");*/
write1_io(WD_COMMAND,IO_WD_ADDR);
write1_io(cmd,IO_WD_DATA);
write1_io(WD_COMMAND, IO_WD_ADDR);
write1_io(cmd, IO_WD_DATA);
}
static uchar read_1_byte(struct IN2000_hostdata *hostdata)
{
uchar asr, x = 0;
uchar asr, x = 0;
write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write_3393_cmd(hostdata,WD_CMD_TRANS_INFO|0x80);
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write_3393_cmd(hostdata, WD_CMD_TRANS_INFO | 0x80);
do {
asr = READ_AUX_STAT();
if (asr & ASR_DBR)
x = read_3393(hostdata,WD_DATA);
x = read_3393(hostdata, WD_DATA);
} while (!(asr & ASR_INT));
return x;
}
......@@ -232,18 +235,18 @@ uchar asr, x = 0;
static void write_3393_count(struct IN2000_hostdata *hostdata, unsigned long value)
{
write1_io(WD_TRANSFER_COUNT_MSB,IO_WD_ADDR);
write1_io((value >> 16),IO_WD_DATA);
write1_io((value >> 8),IO_WD_DATA);
write1_io(value,IO_WD_DATA);
write1_io(WD_TRANSFER_COUNT_MSB, IO_WD_ADDR);
write1_io((value >> 16), IO_WD_DATA);
write1_io((value >> 8), IO_WD_DATA);
write1_io(value, IO_WD_DATA);
}
static unsigned long read_3393_count(struct IN2000_hostdata *hostdata)
{
unsigned long value;
unsigned long value;
write1_io(WD_TRANSFER_COUNT_MSB,IO_WD_ADDR);
write1_io(WD_TRANSFER_COUNT_MSB, IO_WD_ADDR);
value = read1_io(IO_WD_DATA) << 16;
value |= read1_io(IO_WD_DATA) << 8;
value |= read1_io(IO_WD_DATA);
......@@ -256,19 +259,38 @@ unsigned long value;
* will be a DATA_OUT phase with this command, false otherwise.
* (Thanks to Joerg Dorchain for the research and suggestion.)
*/
static int is_dir_out(Scsi_Cmnd *cmd)
static int is_dir_out(Scsi_Cmnd * cmd)
{
switch (cmd->cmnd[0]) {
case WRITE_6: case WRITE_10: case WRITE_12:
case WRITE_LONG: case WRITE_SAME: case WRITE_BUFFER:
case WRITE_VERIFY: case WRITE_VERIFY_12:
case COMPARE: case COPY: case COPY_VERIFY:
case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
case SEARCH_EQUAL_12: case SEARCH_HIGH_12: case SEARCH_LOW_12:
case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
case MODE_SELECT: case MODE_SELECT_10: case LOG_SELECT:
case SEND_DIAGNOSTIC: case CHANGE_DEFINITION: case UPDATE_BLOCK:
case SET_WINDOW: case MEDIUM_SCAN: case SEND_VOLUME_TAG:
case WRITE_6:
case WRITE_10:
case WRITE_12:
case WRITE_LONG:
case WRITE_SAME:
case WRITE_BUFFER:
case WRITE_VERIFY:
case WRITE_VERIFY_12:
case COMPARE:
case COPY:
case COPY_VERIFY:
case SEARCH_EQUAL:
case SEARCH_HIGH:
case SEARCH_LOW:
case SEARCH_EQUAL_12:
case SEARCH_HIGH_12:
case SEARCH_LOW_12:
case FORMAT_UNIT:
case REASSIGN_BLOCKS:
case RESERVE:
case MODE_SELECT:
case MODE_SELECT_10:
case LOG_SELECT:
case SEND_DIAGNOSTIC:
case CHANGE_DEFINITION:
case UPDATE_BLOCK:
case SET_WINDOW:
case MEDIUM_SCAN:
case SEND_VOLUME_TAG:
case 0xea:
return 1;
default:
......@@ -279,23 +301,23 @@ static int is_dir_out(Scsi_Cmnd *cmd)
static struct sx_period sx_table[] = {
{ 1, 0x20},
{1, 0x20},
{252, 0x20},
{376, 0x30},
{500, 0x40},
{624, 0x50},
{752, 0x60},
{876, 0x70},
{1000,0x00},
{0, 0} };
{1000, 0x00},
{0, 0}
};
static int round_period(unsigned int period)
{
int x;
int x;
for (x=1; sx_table[x].period_ns; x++) {
if ((period <= sx_table[x-0].period_ns) &&
(period > sx_table[x-1].period_ns)) {
for (x = 1; sx_table[x].period_ns; x++) {
if ((period <= sx_table[x - 0].period_ns) && (period > sx_table[x - 1].period_ns)) {
return x;
}
}
......@@ -304,11 +326,11 @@ int x;
static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
{
uchar result;
uchar result;
period *= 4; /* convert SDTR code to ns */
result = sx_table[round_period(period)].reg_value;
result |= (offset < OPTIMUM_SX_OFF)?offset:OPTIMUM_SX_OFF;
result |= (offset < OPTIMUM_SX_OFF) ? offset : OPTIMUM_SX_OFF;
return result;
}
......@@ -316,24 +338,22 @@ uchar result;
static void in2000_execute(struct Scsi_Host *instance);
static int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *tmp;
unsigned long flags;
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *tmp;
instance = cmd->host;
hostdata = (struct IN2000_hostdata *)instance->hostdata;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid))
DB(DB_QUEUE_COMMAND, printk("Q-%d-%02x-%ld(", cmd->target, cmd->cmnd[0], cmd->pid))
/* Set up a few fields in the Scsi_Cmnd structure for our own use:
* - host_scribble is the pointer to the next cmd in the input queue
* - scsi_done points to the routine we call when a cmd is finished
* - result is what you'd expect
*/
cmd->host_scribble = NULL;
cmd->scsi_done = done;
cmd->result = 0;
......@@ -354,15 +374,14 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid))
*/
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *)cmd->buffer;
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+cmd->SCp.buffer->offset;
cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
}
else {
} else {
cmd->SCp.buffer = NULL;
cmd->SCp.buffers_residual = 0;
cmd->SCp.ptr = (char *)cmd->request_buffer;
cmd->SCp.ptr = (char *) cmd->request_buffer;
cmd->SCp.this_residual = cmd->request_bufflen;
}
cmd->SCp.have_data_in = 0;
......@@ -392,7 +411,6 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid))
* queue and calling in2000_execute().
*/
spin_lock_irqsave(instance->host_lock, flags);
/*
* Add the cmd to the end of 'input_Q'. Note that REQUEST_SENSE
* commands are added to the head of the queue so that the desired
......@@ -400,14 +418,11 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid))
*/
if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) {
cmd->host_scribble = (uchar *)hostdata->input_Q;
cmd->host_scribble = (uchar *) hostdata->input_Q;
hostdata->input_Q = cmd;
}
else { /* find the end of the queue */
for (tmp=(Scsi_Cmnd *)hostdata->input_Q; tmp->host_scribble;
tmp=(Scsi_Cmnd *)tmp->host_scribble)
;
tmp->host_scribble = (uchar *)cmd;
} else { /* find the end of the queue */
for (tmp = (Scsi_Cmnd *) hostdata->input_Q; tmp->host_scribble; tmp = (Scsi_Cmnd *) tmp->host_scribble);
tmp->host_scribble = (uchar *) cmd;
}
/* We know that there's at least one command in 'input_Q' now.
......@@ -416,8 +431,7 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid))
in2000_execute(cmd->host);
DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
spin_unlock_irqrestore(instance->host_lock, flags);
DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid))
return 0;
}
......@@ -431,23 +445,23 @@ DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
* Note that this function is always called with interrupts already
* disabled (either from in2000_queuecommand() or in2000_intr()).
*/
static void in2000_execute (struct Scsi_Host *instance)
static void in2000_execute(struct Scsi_Host *instance)
{
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *cmd, *prev;
int i;
unsigned short *sp;
unsigned short f;
unsigned short flushbuf[16];
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *cmd, *prev;
int i;
unsigned short *sp;
unsigned short f;
unsigned short flushbuf[16];
hostdata = (struct IN2000_hostdata *)instance->hostdata;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
DB(DB_EXECUTE,printk("EX("))
DB(DB_EXECUTE, printk("EX("))
if (hostdata->selecting || hostdata->connected) {
DB(DB_EXECUTE,printk(")EX-0 "))
DB(DB_EXECUTE, printk(")EX-0 "))
return;
}
......@@ -457,20 +471,20 @@ DB(DB_EXECUTE,printk(")EX-0 "))
* for an idle target/lun.
*/
cmd = (Scsi_Cmnd *)hostdata->input_Q;
cmd = (Scsi_Cmnd *) hostdata->input_Q;
prev = 0;
while (cmd) {
if (!(hostdata->busy[cmd->target] & (1 << cmd->lun)))
break;
prev = cmd;
cmd = (Scsi_Cmnd *)cmd->host_scribble;
cmd = (Scsi_Cmnd *) cmd->host_scribble;
}
/* quit if queue empty or all possible targets are busy */
if (!cmd) {
DB(DB_EXECUTE,printk(")EX-1 "))
DB(DB_EXECUTE, printk(")EX-1 "))
return;
}
......@@ -480,7 +494,7 @@ DB(DB_EXECUTE,printk(")EX-1 "))
if (prev)
prev->host_scribble = cmd->host_scribble;
else
hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
hostdata->input_Q = (Scsi_Cmnd *) cmd->host_scribble;
#ifdef PROC_STATISTICS
hostdata->cmd_cnt[cmd->target]++;
......@@ -491,9 +505,9 @@ DB(DB_EXECUTE,printk(")EX-1 "))
*/
if (is_dir_out(cmd))
write_3393(hostdata,WD_DESTINATION_ID, cmd->target);
write_3393(hostdata, WD_DESTINATION_ID, cmd->target);
else
write_3393(hostdata,WD_DESTINATION_ID, cmd->target | DSTID_DPD);
write_3393(hostdata, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
/* Now we need to figure out whether or not this command is a good
* candidate for disconnect/reselect. We guess to the best of our
......@@ -529,33 +543,30 @@ DB(DB_EXECUTE,printk(")EX-1 "))
goto yes;
if (!(hostdata->input_Q)) /* input_Q empty? */
goto no;
for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
prev=(Scsi_Cmnd *)prev->host_scribble) {
for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev; prev = (Scsi_Cmnd *) prev->host_scribble) {
if ((prev->target != cmd->target) || (prev->lun != cmd->lun)) {
for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
prev=(Scsi_Cmnd *)prev->host_scribble)
for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev; prev = (Scsi_Cmnd *) prev->host_scribble)
prev->SCp.phase = 1;
goto yes;
}
}
goto no;
yes:
yes:
cmd->SCp.phase = 1;
#ifdef PROC_STATISTICS
hostdata->disc_allowed_cnt[cmd->target]++;
#endif
no:
write_3393(hostdata,WD_SOURCE_ID,((cmd->SCp.phase)?SRCID_ER:0));
no:
write_3393(hostdata, WD_SOURCE_ID, ((cmd->SCp.phase) ? SRCID_ER : 0));
write_3393(hostdata,WD_TARGET_LUN, cmd->lun);
write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
write_3393(hostdata, WD_TARGET_LUN, cmd->lun);
write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->target]);
hostdata->busy[cmd->target] |= (1 << cmd->lun);
if ((hostdata->level2 <= L2_NONE) ||
(hostdata->sync_stat[cmd->target] == SS_UNSET)) {
if ((hostdata->level2 <= L2_NONE) || (hostdata->sync_stat[cmd->target] == SS_UNSET)) {
/*
* Do a 'Select-With-ATN' command. This will end with
......@@ -584,8 +595,8 @@ DB(DB_EXECUTE,printk(")EX-1 "))
hostdata->sync_stat[cmd->target] = SS_FIRST;
}
hostdata->state = S_SELECTING;
write_3393_count(hostdata,0); /* this guarantees a DATA_PHASE interrupt */
write_3393_cmd(hostdata,WD_CMD_SEL_ATN);
write_3393_count(hostdata, 0); /* this guarantees a DATA_PHASE interrupt */
write_3393_cmd(hostdata, WD_CMD_SEL_ATN);
}
else {
......@@ -599,14 +610,14 @@ DB(DB_EXECUTE,printk(")EX-1 "))
*/
hostdata->connected = cmd;
write_3393(hostdata,WD_COMMAND_PHASE, 0);
write_3393(hostdata, WD_COMMAND_PHASE, 0);
/* copy command_descriptor_block into WD chip
* (take advantage of auto-incrementing)
*/
write1_io(WD_CDB_1, IO_WD_ADDR);
for (i=0; i<cmd->cmd_len; i++)
for (i = 0; i < cmd->cmd_len; i++)
write1_io(cmd->cmnd[i], IO_WD_DATA);
/* The wd33c93 only knows about Group 0, 1, and 5 commands when
......@@ -637,16 +648,16 @@ DB(DB_EXECUTE,printk(")EX-1 "))
if (!(cmd->SCp.phase)) {
write_3393_count(hostdata, cmd->SCp.this_residual);
write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS);
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS);
write1_io(0, IO_FIFO_WRITE); /* clear fifo counter, write mode */
if (is_dir_out(cmd)) {
hostdata->fifo = FI_FIFO_WRITING;
if ((i = cmd->SCp.this_residual) > (IN2000_FIFO_SIZE - 16) )
if ((i = cmd->SCp.this_residual) > (IN2000_FIFO_SIZE - 16))
i = IN2000_FIFO_SIZE - 16;
cmd->SCp.have_data_in = i; /* this much data in fifo */
i >>= 1; /* Gulp. Assuming modulo 2. */
sp = (unsigned short *)cmd->SCp.ptr;
sp = (unsigned short *) cmd->SCp.ptr;
f = hostdata->io_base + IO_FIFO;
#ifdef FAST_WRITE_IO
......@@ -654,7 +665,7 @@ DB(DB_EXECUTE,printk(")EX-1 "))
FAST_WRITE2_IO();
#else
while (i--)
write2_io(*sp++,IO_FIFO);
write2_io(*sp++, IO_FIFO);
#endif
......@@ -669,7 +680,7 @@ DB(DB_EXECUTE,printk(")EX-1 "))
FAST_WRITE2_IO();
#else
while (i--)
write2_io(0,IO_FIFO);
write2_io(0, IO_FIFO);
#endif
......@@ -682,12 +693,11 @@ DB(DB_EXECUTE,printk(")EX-1 "))
cmd->SCp.have_data_in = 0; /* nothing transferred yet */
}
}
else {
write_3393_count(hostdata,0); /* this guarantees a DATA_PHASE interrupt */
} else {
write_3393_count(hostdata, 0); /* this guarantees a DATA_PHASE interrupt */
}
hostdata->state = S_RUNNING_LEVEL2;
write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
write_3393_cmd(hostdata, WD_CMD_SEL_ATN_XFER);
}
/*
......@@ -697,34 +707,32 @@ DB(DB_EXECUTE,printk(")EX-1 "))
* to search the input_Q again...
*/
DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid))
DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->pid))
}
static void transfer_pio(uchar *buf, int cnt,
int data_in_dir, struct IN2000_hostdata *hostdata)
static void transfer_pio(uchar * buf, int cnt, int data_in_dir, struct IN2000_hostdata *hostdata)
{
uchar asr;
uchar asr;
DB(DB_TRANSFER,printk("(%p,%d,%s)",buf,cnt,data_in_dir?"in":"out"))
DB(DB_TRANSFER, printk("(%p,%d,%s)", buf, cnt, data_in_dir ? "in" : "out"))
write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write_3393_count(hostdata,cnt);
write_3393_cmd(hostdata,WD_CMD_TRANS_INFO);
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write_3393_count(hostdata, cnt);
write_3393_cmd(hostdata, WD_CMD_TRANS_INFO);
if (data_in_dir) {
do {
asr = READ_AUX_STAT();
if (asr & ASR_DBR)
*buf++ = read_3393(hostdata,WD_DATA);
*buf++ = read_3393(hostdata, WD_DATA);
} while (!(asr & ASR_INT));
}
else {
} else {
do {
asr = READ_AUX_STAT();
if (asr & ASR_DBR)
write_3393(hostdata,WD_DATA, *buf++);
write_3393(hostdata, WD_DATA, *buf++);
} while (!(asr & ASR_INT));
}
......@@ -739,14 +747,14 @@ DB(DB_TRANSFER,printk("(%p,%d,%s)",buf,cnt,data_in_dir?"in":"out"))
static void transfer_bytes(Scsi_Cmnd *cmd, int data_in_dir)
static void transfer_bytes(Scsi_Cmnd * cmd, int data_in_dir)
{
struct IN2000_hostdata *hostdata;
unsigned short *sp;
unsigned short f;
int i;
struct IN2000_hostdata *hostdata;
unsigned short *sp;
unsigned short f;
int i;
hostdata = (struct IN2000_hostdata *)cmd->host->hostdata;
hostdata = (struct IN2000_hostdata *) cmd->host->hostdata;
/* Normally, you'd expect 'this_residual' to be non-zero here.
* In a series of scatter-gather transfers, however, this
......@@ -765,25 +773,23 @@ int i;
/* Set up hardware registers */
write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
write_3393_count(hostdata,cmd->SCp.this_residual);
write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS);
write1_io(0,IO_FIFO_WRITE); /* zero counter, assume write */
write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->target]);
write_3393_count(hostdata, cmd->SCp.this_residual);
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS);
write1_io(0, IO_FIFO_WRITE); /* zero counter, assume write */
/* Reading is easy. Just issue the command and return - we'll
* get an interrupt later when we have actual data to worry about.
*/
if (data_in_dir) {
write1_io(0,IO_FIFO_READ);
if ((hostdata->level2 >= L2_DATA) ||
(hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
write_3393(hostdata,WD_COMMAND_PHASE,0x45);
write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
write1_io(0, IO_FIFO_READ);
if ((hostdata->level2 >= L2_DATA) || (hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
write_3393(hostdata, WD_COMMAND_PHASE, 0x45);
write_3393_cmd(hostdata, WD_CMD_SEL_ATN_XFER);
hostdata->state = S_RUNNING_LEVEL2;
}
else
write_3393_cmd(hostdata,WD_CMD_TRANS_INFO);
} else
write_3393_cmd(hostdata, WD_CMD_TRANS_INFO);
hostdata->fifo = FI_FIFO_READING;
cmd->SCp.have_data_in = 0;
return;
......@@ -794,16 +800,14 @@ int i;
* write any bytes that don't make it at this stage.
*/
if ((hostdata->level2 >= L2_DATA) ||
(hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
write_3393(hostdata,WD_COMMAND_PHASE,0x45);
write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
if ((hostdata->level2 >= L2_DATA) || (hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
write_3393(hostdata, WD_COMMAND_PHASE, 0x45);
write_3393_cmd(hostdata, WD_CMD_SEL_ATN_XFER);
hostdata->state = S_RUNNING_LEVEL2;
}
else
write_3393_cmd(hostdata,WD_CMD_TRANS_INFO);
} else
write_3393_cmd(hostdata, WD_CMD_TRANS_INFO);
hostdata->fifo = FI_FIFO_WRITING;
sp = (unsigned short *)cmd->SCp.ptr;
sp = (unsigned short *) cmd->SCp.ptr;
if ((i = cmd->SCp.this_residual) > IN2000_FIFO_SIZE)
i = IN2000_FIFO_SIZE;
......@@ -816,7 +820,7 @@ int i;
FAST_WRITE2_IO();
#else
while (i--)
write2_io(*sp++,IO_FIFO);
write2_io(*sp++, IO_FIFO);
#endif
......@@ -829,19 +833,19 @@ int i;
* but it _does_ need to be able to compile and run in an SMP kernel.)
*/
static void in2000_intr (int irqnum, void * dev_id, struct pt_regs *ptregs)
static void in2000_intr(int irqnum, void *dev_id, struct pt_regs *ptregs)
{
struct Scsi_Host *instance = dev_id;
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *patch, *cmd;
uchar asr, sr, phs, id, lun, *ucp, msg;
int i,j;
unsigned long length;
unsigned short *sp;
unsigned short f;
unsigned long flags;
hostdata = (struct IN2000_hostdata *)instance->hostdata;
struct Scsi_Host *instance = dev_id;
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *patch, *cmd;
uchar asr, sr, phs, id, lun, *ucp, msg;
int i, j;
unsigned long length;
unsigned short *sp;
unsigned short f;
unsigned long flags;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
/* Get the spin_lock and disable further ints, for SMP */
......@@ -909,14 +913,14 @@ unsigned long flags;
* (Big thanks to Bill Earnest for getting me out of the mud in here.)
*/
cmd = (Scsi_Cmnd *)hostdata->connected; /* assume we're connected */
CHECK_NULL(cmd,"fifo_int")
cmd = (Scsi_Cmnd *) hostdata->connected; /* assume we're connected */
CHECK_NULL(cmd, "fifo_int")
if (hostdata->fifo == FI_FIFO_READING) {
DB(DB_FIFO,printk("{R:%02x} ",read1_io(IO_FIFO_COUNT)))
DB(DB_FIFO, printk("{R:%02x} ", read1_io(IO_FIFO_COUNT)))
sp = (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
sp = (unsigned short *) (cmd->SCp.ptr + cmd->SCp.have_data_in);
i = read1_io(IO_FIFO_COUNT) & 0xfe;
i <<= 2; /* # of words waiting in the fifo */
f = hostdata->io_base + IO_FIFO;
......@@ -930,14 +934,14 @@ DB(DB_FIFO,printk("{R:%02x} ",read1_io(IO_FIFO_COUNT)))
#endif
i = sp - (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
i = sp - (unsigned short *) (cmd->SCp.ptr + cmd->SCp.have_data_in);
i <<= 1;
cmd->SCp.have_data_in += i;
}
else if (hostdata->fifo == FI_FIFO_WRITING) {
DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT)))
DB(DB_FIFO, printk("{W:%02x} ", read1_io(IO_FIFO_COUNT)))
/* If all bytes have been written to the fifo, flush out the stragglers.
* Note that while writing 16 dummy words seems arbitrary, we don't
......@@ -949,11 +953,10 @@ DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT)))
* UPDATE: Bill says this is exactly what Always does, so there.
* More thanks due him for help in this section.
*/
if (cmd->SCp.this_residual == cmd->SCp.have_data_in) {
i = 16;
while (i--) /* write 32 dummy bytes */
write2_io(0,IO_FIFO);
write2_io(0, IO_FIFO);
}
/* If there are still bytes left in the SCSI buffer, write as many as we
......@@ -961,16 +964,16 @@ DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT)))
*/
else {
sp = (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
sp = (unsigned short *) (cmd->SCp.ptr + cmd->SCp.have_data_in);
i = cmd->SCp.this_residual - cmd->SCp.have_data_in; /* bytes yet to go */
j = read1_io(IO_FIFO_COUNT) & 0xfe;
j <<= 2; /* how many words the fifo has room for */
if ((j << 1) > i)
j = (i >> 1);
while (j--)
write2_io(*sp++,IO_FIFO);
write2_io(*sp++, IO_FIFO);
i = sp - (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
i = sp - (unsigned short *) (cmd->SCp.ptr + cmd->SCp.have_data_in);
i <<= 1;
cmd->SCp.have_data_in += i;
}
......@@ -992,9 +995,9 @@ DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT)))
* detailed info from FIFO_READING and FIFO_WRITING (see below).
*/
cmd = (Scsi_Cmnd *)hostdata->connected; /* assume we're connected */
sr = read_3393(hostdata,WD_SCSI_STATUS); /* clear the interrupt */
phs = read_3393(hostdata,WD_COMMAND_PHASE);
cmd = (Scsi_Cmnd *) hostdata->connected; /* assume we're connected */
sr = read_3393(hostdata, WD_SCSI_STATUS); /* clear the interrupt */
phs = read_3393(hostdata, WD_COMMAND_PHASE);
if (!cmd && (sr != CSR_RESEL_AM && sr != CSR_TIMEOUT && sr != CSR_SELECT)) {
printk("\nNR:wd-intr-1\n");
......@@ -1005,7 +1008,7 @@ DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT)))
return;
}
DB(DB_INTR,printk("{%02x:%02x-",asr,sr))
DB(DB_INTR, printk("{%02x:%02x-", asr, sr))
/* After starting a FIFO-based transfer, the next _WD3393_ interrupt is
* guaranteed to be in response to the completion of the transfer.
......@@ -1019,12 +1022,11 @@ DB(DB_INTR,printk("{%02x:%02x-",asr,sr))
* After doing whatever is necessary with the fifo, we go on and
* service the WD3393 interrupt normally.
*/
if (hostdata->fifo == FI_FIFO_READING) {
/* buffer index = start-of-buffer + #-of-bytes-already-read */
sp = (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
sp = (unsigned short *) (cmd->SCp.ptr + cmd->SCp.have_data_in);
/* bytes remaining in fifo = (total-wanted - #-not-got) - #-already-read */
......@@ -1046,7 +1048,7 @@ DB(DB_INTR,printk("{%02x:%02x-",asr,sr))
cmd->SCp.this_residual = read_3393_count(hostdata);
cmd->SCp.ptr += (length - cmd->SCp.this_residual);
DB(DB_TRANSFER,printk("(%p,%d)",cmd->SCp.ptr,cmd->SCp.this_residual))
DB(DB_TRANSFER, printk("(%p,%d)", cmd->SCp.ptr, cmd->SCp.this_residual))
}
......@@ -1056,7 +1058,7 @@ DB(DB_TRANSFER,printk("(%p,%d)",cmd->SCp.ptr,cmd->SCp.this_residual))
cmd->SCp.this_residual = read_3393_count(hostdata);
cmd->SCp.ptr += (length - cmd->SCp.this_residual);
DB(DB_TRANSFER,printk("(%p,%d)",cmd->SCp.ptr,cmd->SCp.this_residual))
DB(DB_TRANSFER, printk("(%p,%d)", cmd->SCp.ptr, cmd->SCp.this_residual))
}
......@@ -1065,13 +1067,13 @@ DB(DB_TRANSFER,printk("(%p,%d)",cmd->SCp.ptr,cmd->SCp.this_residual))
switch (sr) {
case CSR_TIMEOUT:
DB(DB_INTR,printk("TIMEOUT"))
DB(DB_INTR, printk("TIMEOUT"))
if (hostdata->state == S_RUNNING_LEVEL2)
hostdata->connected = NULL;
else {
cmd = (Scsi_Cmnd *)hostdata->selecting; /* get a valid cmd */
CHECK_NULL(cmd,"csr_timeout")
cmd = (Scsi_Cmnd *) hostdata->selecting; /* get a valid cmd */
CHECK_NULL(cmd, "csr_timeout")
hostdata->selecting = NULL;
}
......@@ -1091,9 +1093,9 @@ CHECK_NULL(cmd,"csr_timeout")
/* Note: this interrupt should not occur in a LEVEL2 command */
case CSR_SELECT:
DB(DB_INTR,printk("SELECT"))
hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting;
CHECK_NULL(cmd,"csr_select")
DB(DB_INTR, printk("SELECT"))
hostdata->connected = cmd = (Scsi_Cmnd *) hostdata->selecting;
CHECK_NULL(cmd, "csr_select")
hostdata->selecting = NULL;
/* construct an IDENTIFY message with correct disconnect bit */
......@@ -1104,7 +1106,7 @@ CHECK_NULL(cmd,"csr_select")
if (hostdata->sync_stat[cmd->target] == SS_FIRST) {
#ifdef SYNC_DEBUG
printk(" sending SDTR ");
printk(" sending SDTR ");
#endif
hostdata->sync_stat[cmd->target] = SS_WAITING;
......@@ -1114,31 +1116,30 @@ printk(" sending SDTR ");
hostdata->outgoing_msg[1] = EXTENDED_MESSAGE;
hostdata->outgoing_msg[2] = 3;
hostdata->outgoing_msg[3] = EXTENDED_SDTR;
hostdata->outgoing_msg[4] = OPTIMUM_SX_PER/4;
hostdata->outgoing_msg[4] = OPTIMUM_SX_PER / 4;
hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF;
hostdata->outgoing_len = 6;
}
else
} else
hostdata->outgoing_len = 1;
hostdata->state = S_CONNECTED;
break;
case CSR_XFER_DONE|PHS_DATA_IN:
case CSR_UNEXP |PHS_DATA_IN:
case CSR_SRV_REQ |PHS_DATA_IN:
DB(DB_INTR,printk("IN-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
case CSR_XFER_DONE | PHS_DATA_IN:
case CSR_UNEXP | PHS_DATA_IN:
case CSR_SRV_REQ | PHS_DATA_IN:
DB(DB_INTR, printk("IN-%d.%d", cmd->SCp.this_residual, cmd->SCp.buffers_residual))
transfer_bytes(cmd, DATA_IN_DIR);
if (hostdata->state != S_RUNNING_LEVEL2)
hostdata->state = S_CONNECTED;
break;
case CSR_XFER_DONE|PHS_DATA_OUT:
case CSR_UNEXP |PHS_DATA_OUT:
case CSR_SRV_REQ |PHS_DATA_OUT:
DB(DB_INTR,printk("OUT-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
case CSR_XFER_DONE | PHS_DATA_OUT:
case CSR_UNEXP | PHS_DATA_OUT:
case CSR_SRV_REQ | PHS_DATA_OUT:
DB(DB_INTR, printk("OUT-%d.%d", cmd->SCp.this_residual, cmd->SCp.buffers_residual))
transfer_bytes(cmd, DATA_OUT_DIR);
if (hostdata->state != S_RUNNING_LEVEL2)
hostdata->state = S_CONNECTED;
......@@ -1147,41 +1148,40 @@ DB(DB_INTR,printk("OUT-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
/* Note: this interrupt should not occur in a LEVEL2 command */
case CSR_XFER_DONE|PHS_COMMAND:
case CSR_UNEXP |PHS_COMMAND:
case CSR_SRV_REQ |PHS_COMMAND:
DB(DB_INTR,printk("CMND-%02x,%ld",cmd->cmnd[0],cmd->pid))
case CSR_XFER_DONE | PHS_COMMAND:
case CSR_UNEXP | PHS_COMMAND:
case CSR_SRV_REQ | PHS_COMMAND:
DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->pid))
transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata);
hostdata->state = S_CONNECTED;
break;
case CSR_XFER_DONE|PHS_STATUS:
case CSR_UNEXP |PHS_STATUS:
case CSR_SRV_REQ |PHS_STATUS:
DB(DB_INTR,printk("STATUS="))
case CSR_XFER_DONE | PHS_STATUS:
case CSR_UNEXP | PHS_STATUS:
case CSR_SRV_REQ | PHS_STATUS:
DB(DB_INTR, printk("STATUS="))
cmd->SCp.Status = read_1_byte(hostdata);
DB(DB_INTR,printk("%02x",cmd->SCp.Status))
DB(DB_INTR, printk("%02x", cmd->SCp.Status))
if (hostdata->level2 >= L2_BASIC) {
sr = read_3393(hostdata,WD_SCSI_STATUS); /* clear interrupt */
sr = read_3393(hostdata, WD_SCSI_STATUS); /* clear interrupt */
hostdata->state = S_RUNNING_LEVEL2;
write_3393(hostdata,WD_COMMAND_PHASE, 0x50);
write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
}
else {
write_3393(hostdata, WD_COMMAND_PHASE, 0x50);
write_3393_cmd(hostdata, WD_CMD_SEL_ATN_XFER);
} else {
hostdata->state = S_CONNECTED;
}
break;
case CSR_XFER_DONE|PHS_MESS_IN:
case CSR_UNEXP |PHS_MESS_IN:
case CSR_SRV_REQ |PHS_MESS_IN:
DB(DB_INTR,printk("MSG_IN="))
case CSR_XFER_DONE | PHS_MESS_IN:
case CSR_UNEXP | PHS_MESS_IN:
case CSR_SRV_REQ | PHS_MESS_IN:
DB(DB_INTR, printk("MSG_IN="))
msg = read_1_byte(hostdata);
sr = read_3393(hostdata,WD_SCSI_STATUS); /* clear interrupt */
sr = read_3393(hostdata, WD_SCSI_STATUS); /* clear interrupt */
hostdata->incoming_msg[hostdata->incoming_ptr] = msg;
if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE)
......@@ -1193,64 +1193,62 @@ DB(DB_INTR,printk("MSG_IN="))
switch (msg) {
case COMMAND_COMPLETE:
DB(DB_INTR,printk("CCMP-%ld",cmd->pid))
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
DB(DB_INTR, printk("CCMP-%ld", cmd->pid))
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_PRE_CMP_DISC;
break;
case SAVE_POINTERS:
DB(DB_INTR,printk("SDP"))
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
DB(DB_INTR, printk("SDP"))
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
break;
case RESTORE_POINTERS:
DB(DB_INTR,printk("RDP"))
DB(DB_INTR, printk("RDP"))
if (hostdata->level2 >= L2_BASIC) {
write_3393(hostdata,WD_COMMAND_PHASE, 0x45);
write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
write_3393(hostdata, WD_COMMAND_PHASE, 0x45);
write_3393_cmd(hostdata, WD_CMD_SEL_ATN_XFER);
hostdata->state = S_RUNNING_LEVEL2;
}
else {
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
} else {
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
}
break;
case DISCONNECT:
DB(DB_INTR,printk("DIS"))
DB(DB_INTR, printk("DIS"))
cmd->device->disconnect = 1;
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_PRE_TMP_DISC;
break;
case MESSAGE_REJECT:
DB(DB_INTR,printk("REJ"))
DB(DB_INTR, printk("REJ"))
#ifdef SYNC_DEBUG
printk("-REJ-");
printk("-REJ-");
#endif
if (hostdata->sync_stat[cmd->target] == SS_WAITING)
hostdata->sync_stat[cmd->target] = SS_SET;
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
break;
case EXTENDED_MESSAGE:
DB(DB_INTR,printk("EXT"))
DB(DB_INTR, printk("EXT"))
ucp = hostdata->incoming_msg;
#ifdef SYNC_DEBUG
printk("%02x",ucp[hostdata->incoming_ptr]);
printk("%02x", ucp[hostdata->incoming_ptr]);
#endif
/* Is this the last byte of the extended message? */
if ((hostdata->incoming_ptr >= 2) &&
(hostdata->incoming_ptr == (ucp[1] + 1))) {
if ((hostdata->incoming_ptr >= 2) && (hostdata->incoming_ptr == (ucp[1] + 1))) {
switch (ucp[2]) { /* what's the EXTENDED code? */
case EXTENDED_SDTR:
id = calc_sync_xfer(ucp[3],ucp[4]);
id = calc_sync_xfer(ucp[3], ucp[4]);
if (hostdata->sync_stat[cmd->target] != SS_WAITING) {
/* A device has sent an unsolicited SDTR message; rather than go
......@@ -1262,43 +1260,41 @@ printk("%02x",ucp[hostdata->incoming_ptr]);
* specifically ask for sync transfers, we won't do any.
*/
write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
write_3393_cmd(hostdata, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
hostdata->outgoing_msg[1] = 3;
hostdata->outgoing_msg[2] = EXTENDED_SDTR;
hostdata->outgoing_msg[3] = hostdata->default_sx_per/4;
hostdata->outgoing_msg[3] = hostdata->default_sx_per / 4;
hostdata->outgoing_msg[4] = 0;
hostdata->outgoing_len = 5;
hostdata->sync_xfer[cmd->target] =
calc_sync_xfer(hostdata->default_sx_per/4,0);
}
else {
hostdata->sync_xfer[cmd->target] = calc_sync_xfer(hostdata->default_sx_per / 4, 0);
} else {
hostdata->sync_xfer[cmd->target] = id;
}
#ifdef SYNC_DEBUG
printk("sync_xfer=%02x",hostdata->sync_xfer[cmd->target]);
printk("sync_xfer=%02x", hostdata->sync_xfer[cmd->target]);
#endif
hostdata->sync_stat[cmd->target] = SS_SET;
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
break;
case EXTENDED_WDTR:
write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
write_3393_cmd(hostdata, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
printk("sending WDTR ");
hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
hostdata->outgoing_msg[1] = 2;
hostdata->outgoing_msg[2] = EXTENDED_WDTR;
hostdata->outgoing_msg[3] = 0; /* 8 bit transfer width */
hostdata->outgoing_len = 4;
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
break;
default:
write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
printk("Rejecting Unknown Extended Message(%02x). ",ucp[2]);
write_3393_cmd(hostdata, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
printk("Rejecting Unknown Extended Message(%02x). ", ucp[2]);
hostdata->outgoing_msg[0] = MESSAGE_REJECT;
hostdata->outgoing_len = 1;
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
break;
}
......@@ -1309,17 +1305,17 @@ printk("sync_xfer=%02x",hostdata->sync_xfer[cmd->target]);
else {
hostdata->incoming_ptr++;
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
}
break;
default:
printk("Rejecting Unknown Message(%02x) ",msg);
write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
printk("Rejecting Unknown Message(%02x) ", msg);
write_3393_cmd(hostdata, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
hostdata->outgoing_msg[0] = MESSAGE_REJECT;
hostdata->outgoing_len = 1;
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_CONNECTED;
}
break;
......@@ -1333,12 +1329,12 @@ printk("sync_xfer=%02x",hostdata->sync_xfer[cmd->target]);
* have been turned off for the command that just completed.
*/
write_3393(hostdata,WD_SOURCE_ID, SRCID_ER);
write_3393(hostdata, WD_SOURCE_ID, SRCID_ER);
if (phs == 0x60) {
DB(DB_INTR,printk("SX-DONE-%ld",cmd->pid))
DB(DB_INTR, printk("SX-DONE-%ld", cmd->pid))
cmd->SCp.Message = COMMAND_COMPLETE;
lun = read_3393(hostdata,WD_TARGET_LUN);
DB(DB_INTR,printk(":%d.%d",cmd->SCp.Status,lun))
lun = read_3393(hostdata, WD_TARGET_LUN);
DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun))
hostdata->connected = NULL;
hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
hostdata->state = S_UNCONNECTED;
......@@ -1355,9 +1351,8 @@ DB(DB_INTR,printk(":%d.%d",cmd->SCp.Status,lun))
*/
in2000_execute(instance);
}
else {
printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---",asr,sr,phs,cmd->pid);
} else {
printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->pid);
}
break;
......@@ -1365,17 +1360,17 @@ DB(DB_INTR,printk(":%d.%d",cmd->SCp.Status,lun))
/* Note: this interrupt will occur only after a LEVEL2 command */
case CSR_SDP:
DB(DB_INTR,printk("SDP"))
DB(DB_INTR, printk("SDP"))
hostdata->state = S_RUNNING_LEVEL2;
write_3393(hostdata,WD_COMMAND_PHASE, 0x41);
write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
write_3393(hostdata, WD_COMMAND_PHASE, 0x41);
write_3393_cmd(hostdata, WD_CMD_SEL_ATN_XFER);
break;
case CSR_XFER_DONE|PHS_MESS_OUT:
case CSR_UNEXP |PHS_MESS_OUT:
case CSR_SRV_REQ |PHS_MESS_OUT:
DB(DB_INTR,printk("MSG_OUT="))
case CSR_XFER_DONE | PHS_MESS_OUT:
case CSR_UNEXP | PHS_MESS_OUT:
case CSR_SRV_REQ | PHS_MESS_OUT:
DB(DB_INTR, printk("MSG_OUT="))
/* To get here, we've probably requested MESSAGE_OUT and have
* already put the correct bytes in outgoing_msg[] and filled
......@@ -1389,14 +1384,12 @@ DB(DB_INTR,printk("MSG_OUT="))
* NOP messages in these situations results in no harm and
* makes everyone happy.
*/
if (hostdata->outgoing_len == 0) {
hostdata->outgoing_len = 1;
hostdata->outgoing_msg[0] = NOP;
}
transfer_pio(hostdata->outgoing_msg, hostdata->outgoing_len,
DATA_OUT_DIR, hostdata);
DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0]))
transfer_pio(hostdata->outgoing_msg, hostdata->outgoing_len, DATA_OUT_DIR, hostdata);
DB(DB_INTR, printk("%02x", hostdata->outgoing_msg[0]))
hostdata->outgoing_len = 0;
hostdata->state = S_CONNECTED;
break;
......@@ -1417,7 +1410,7 @@ DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0]))
* have been turned off for the command that just completed.
*/
write_3393(hostdata,WD_SOURCE_ID, SRCID_ER);
write_3393(hostdata, WD_SOURCE_ID, SRCID_ER);
if (cmd == NULL) {
printk(" - Already disconnected! ");
hostdata->state = S_UNCONNECTED;
......@@ -1426,7 +1419,7 @@ DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0]))
spin_unlock_irqrestore(instance->host_lock, flags);
return;
}
DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid))
DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid))
hostdata->connected = NULL;
hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
hostdata->state = S_UNCONNECTED;
......@@ -1450,8 +1443,8 @@ DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid))
* have been turned off for the command that just completed.
*/
write_3393(hostdata,WD_SOURCE_ID, SRCID_ER);
DB(DB_INTR,printk("DISC-%ld",cmd->pid))
write_3393(hostdata, WD_SOURCE_ID, SRCID_ER);
DB(DB_INTR, printk("DISC-%ld", cmd->pid))
if (cmd == NULL) {
printk(" - Already disconnected! ");
hostdata->state = S_UNCONNECTED;
......@@ -1461,7 +1454,7 @@ DB(DB_INTR,printk("DISC-%ld",cmd->pid))
hostdata->connected = NULL;
hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
hostdata->state = S_UNCONNECTED;
DB(DB_INTR,printk(":%d",cmd->SCp.Status))
DB(DB_INTR, printk(":%d", cmd->SCp.Status))
if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
else
......@@ -1470,7 +1463,7 @@ DB(DB_INTR,printk(":%d",cmd->SCp.Status))
break;
case S_PRE_TMP_DISC:
case S_RUNNING_LEVEL2:
cmd->host_scribble = (uchar *)hostdata->disconnected_Q;
cmd->host_scribble = (uchar *) hostdata->disconnected_Q;
hostdata->disconnected_Q = cmd;
hostdata->connected = NULL;
hostdata->state = S_UNCONNECTED;
......@@ -1494,19 +1487,18 @@ DB(DB_INTR,printk(":%d",cmd->SCp.Status))
case CSR_RESEL_AM:
DB(DB_INTR,printk("RESEL"))
DB(DB_INTR, printk("RESEL"))
/* First we have to make sure this reselection didn't */
/* happen during Arbitration/Selection of some other device. */
/* If yes, put losing command back on top of input_Q. */
if (hostdata->level2 <= L2_NONE) {
if (hostdata->selecting) {
cmd = (Scsi_Cmnd *)hostdata->selecting;
cmd = (Scsi_Cmnd *) hostdata->selecting;
hostdata->selecting = NULL;
hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
cmd->host_scribble = (uchar *)hostdata->input_Q;
cmd->host_scribble = (uchar *) hostdata->input_Q;
hostdata->input_Q = cmd;
}
}
......@@ -1516,11 +1508,10 @@ DB(DB_INTR,printk("RESEL"))
if (cmd) {
if (phs == 0x00) {
hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
cmd->host_scribble = (uchar *)hostdata->input_Q;
cmd->host_scribble = (uchar *) hostdata->input_Q;
hostdata->input_Q = cmd;
}
else {
printk("---%02x:%02x:%02x-TROUBLE: Intrusive ReSelect!---",asr,sr,phs);
} else {
printk("---%02x:%02x:%02x-TROUBLE: Intrusive ReSelect!---", asr, sr, phs);
while (1)
printk("\r");
}
......@@ -1530,7 +1521,7 @@ DB(DB_INTR,printk("RESEL"))
/* OK - find out which device reselected us. */
id = read_3393(hostdata,WD_SOURCE_ID);
id = read_3393(hostdata, WD_SOURCE_ID);
id &= SRCID_MASK;
/* and extract the lun from the ID message. (Note that we don't
......@@ -1538,26 +1529,26 @@ DB(DB_INTR,printk("RESEL"))
* not the right way to go, but....)
*/
lun = read_3393(hostdata,WD_DATA);
lun = read_3393(hostdata, WD_DATA);
if (hostdata->level2 < L2_RESELECT)
write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
lun &= 7;
/* Now we look for the command that's reconnecting. */
cmd = (Scsi_Cmnd *)hostdata->disconnected_Q;
cmd = (Scsi_Cmnd *) hostdata->disconnected_Q;
patch = NULL;
while (cmd) {
if (id == cmd->target && lun == cmd->lun)
break;
patch = cmd;
cmd = (Scsi_Cmnd *)cmd->host_scribble;
cmd = (Scsi_Cmnd *) cmd->host_scribble;
}
/* Hmm. Couldn't find a valid command.... What to do? */
if (!cmd) {
printk("---TROUBLE: target %d.%d not in disconnect queue---",id,lun);
printk("---TROUBLE: target %d.%d not in disconnect queue---", id, lun);
break;
}
......@@ -1566,7 +1557,7 @@ DB(DB_INTR,printk("RESEL"))
if (patch)
patch->host_scribble = cmd->host_scribble;
else
hostdata->disconnected_Q = (Scsi_Cmnd *)cmd->host_scribble;
hostdata->disconnected_Q = (Scsi_Cmnd *) cmd->host_scribble;
hostdata->connected = cmd;
/* We don't need to worry about 'initialize_SCp()' or 'hostdata->busy[]'
......@@ -1575,28 +1566,27 @@ DB(DB_INTR,printk("RESEL"))
*/
if (is_dir_out(cmd))
write_3393(hostdata,WD_DESTINATION_ID,cmd->target);
write_3393(hostdata, WD_DESTINATION_ID, cmd->target);
else
write_3393(hostdata,WD_DESTINATION_ID,cmd->target | DSTID_DPD);
write_3393(hostdata, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
if (hostdata->level2 >= L2_RESELECT) {
write_3393_count(hostdata,0); /* we want a DATA_PHASE interrupt */
write_3393(hostdata,WD_COMMAND_PHASE, 0x45);
write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
write_3393_count(hostdata, 0); /* we want a DATA_PHASE interrupt */
write_3393(hostdata, WD_COMMAND_PHASE, 0x45);
write_3393_cmd(hostdata, WD_CMD_SEL_ATN_XFER);
hostdata->state = S_RUNNING_LEVEL2;
}
else
} else
hostdata->state = S_CONNECTED;
DB(DB_INTR,printk("-%ld",cmd->pid))
DB(DB_INTR, printk("-%ld", cmd->pid))
break;
default:
printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs);
printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--", asr, sr, phs);
}
write1_io(0, IO_LED_OFF);
DB(DB_INTR,printk("} "))
DB(DB_INTR, printk("} "))
/* release the SMP spin_lock and restore irq state */
spin_unlock_irqrestore(instance->host_lock, flags);
......@@ -1615,65 +1605,61 @@ DB(DB_INTR,printk("} "))
static int reset_hardware(struct Scsi_Host *instance, int type)
{
struct IN2000_hostdata *hostdata;
int qt,x;
struct IN2000_hostdata *hostdata;
int qt, x;
hostdata = (struct IN2000_hostdata *)instance->hostdata;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
write1_io(0, IO_LED_ON);
if (type == RESET_CARD_AND_BUS) {
write1_io(0,IO_CARD_RESET);
write1_io(0, IO_CARD_RESET);
x = read1_io(IO_HARDWARE);
}
x = read_3393(hostdata,WD_SCSI_STATUS); /* clear any WD intrpt */
write_3393(hostdata,WD_OWN_ID, instance->this_id |
OWNID_EAF | OWNID_RAF | OWNID_FS_8);
write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER,
calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF));
x = read_3393(hostdata, WD_SCSI_STATUS); /* clear any WD intrpt */
write_3393(hostdata, WD_OWN_ID, instance->this_id | OWNID_EAF | OWNID_RAF | OWNID_FS_8);
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, calc_sync_xfer(hostdata->default_sx_per / 4, DEFAULT_SX_OFF));
write1_io(0,IO_FIFO_WRITE); /* clear fifo counter */
write1_io(0,IO_FIFO_READ); /* start fifo out in read mode */
write_3393(hostdata,WD_COMMAND, WD_CMD_RESET);
write1_io(0, IO_FIFO_WRITE); /* clear fifo counter */
write1_io(0, IO_FIFO_READ); /* start fifo out in read mode */
write_3393(hostdata, WD_COMMAND, WD_CMD_RESET);
/* FIXME: timeout ?? */
while (!(READ_AUX_STAT() & ASR_INT))
cpu_relax(); /* wait for RESET to complete */
x = read_3393(hostdata,WD_SCSI_STATUS); /* clear interrupt */
x = read_3393(hostdata, WD_SCSI_STATUS); /* clear interrupt */
write_3393(hostdata,WD_QUEUE_TAG,0xa5); /* any random number */
qt = read_3393(hostdata,WD_QUEUE_TAG);
write_3393(hostdata, WD_QUEUE_TAG, 0xa5); /* any random number */
qt = read_3393(hostdata, WD_QUEUE_TAG);
if (qt == 0xa5) {
x |= B_FLAG;
write_3393(hostdata,WD_QUEUE_TAG,0);
write_3393(hostdata, WD_QUEUE_TAG, 0);
}
write_3393(hostdata,WD_TIMEOUT_PERIOD, TIMEOUT_PERIOD_VALUE);
write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write_3393(hostdata, WD_TIMEOUT_PERIOD, TIMEOUT_PERIOD_VALUE);
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
write1_io(0, IO_LED_OFF);
return x;
}
static int in2000_bus_reset(Scsi_Cmnd *cmd)
static int in2000_bus_reset(Scsi_Cmnd * cmd)
{
unsigned long flags;
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
int x;
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
int x;
instance = cmd->host;
hostdata = (struct IN2000_hostdata *)instance->hostdata;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no);
spin_lock_irqsave(instance->host_lock, flags);
/* do scsi-reset here */
reset_hardware(instance, RESET_CARD_AND_BUS);
for (x = 0; x < 8; x++) {
hostdata->busy[x] = 0;
hostdata->sync_xfer[x] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
hostdata->sync_xfer[x] = calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF);
hostdata->sync_stat[x] = SS_UNSET; /* using default sync values */
}
hostdata->input_Q = NULL;
......@@ -1686,45 +1672,40 @@ int x;
hostdata->outgoing_len = 0;
cmd->result = DID_RESET << 16;
spin_unlock_irqrestore(instance->host_lock, flags);
return SUCCESS;
}
static int in2000_host_reset(Scsi_Cmnd *cmd)
static int in2000_host_reset(Scsi_Cmnd * cmd)
{
return FAILED;
}
static int in2000_device_reset(Scsi_Cmnd *cmd)
static int in2000_device_reset(Scsi_Cmnd * cmd)
{
return FAILED;
}
static int in2000_abort (Scsi_Cmnd *cmd)
static int in2000_abort(Scsi_Cmnd * cmd)
{
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *tmp, *prev;
unsigned long flags;
uchar sr, asr;
unsigned long timeout;
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
Scsi_Cmnd *tmp, *prev;
uchar sr, asr;
unsigned long timeout;
instance = cmd->host;
hostdata = (struct IN2000_hostdata *)instance->hostdata;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
printk(KERN_DEBUG "scsi%d: Abort-", instance->host_no);
printk("(asr=%02x,count=%ld,resid=%d,buf_resid=%d,have_data=%d,FC=%02x)- ",
READ_AUX_STAT(),read_3393_count(hostdata),cmd->SCp.this_residual,cmd->SCp.buffers_residual,
cmd->SCp.have_data_in,read1_io(IO_FIFO_COUNT));
printk("(asr=%02x,count=%ld,resid=%d,buf_resid=%d,have_data=%d,FC=%02x)- ", READ_AUX_STAT(), read_3393_count(hostdata), cmd->SCp.this_residual, cmd->SCp.buffers_residual, cmd->SCp.have_data_in, read1_io(IO_FIFO_COUNT));
/*
* Case 1 : If the command hasn't been issued yet, we simply remove it
* from the inout_Q.
*/
spin_lock_irqsave(instance->host_lock, flags);
tmp = (Scsi_Cmnd *)hostdata->input_Q;
tmp = (Scsi_Cmnd *) hostdata->input_Q;
prev = 0;
while (tmp) {
if (tmp == cmd) {
......@@ -1732,14 +1713,12 @@ unsigned long timeout;
prev->host_scribble = cmd->host_scribble;
cmd->host_scribble = NULL;
cmd->result = DID_ABORT << 16;
printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ",
instance->host_no, cmd->pid);
printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->pid);
cmd->scsi_done(cmd);
spin_unlock_irqrestore(instance->host_lock, flags);
return SUCCESS;
}
prev = tmp;
tmp = (Scsi_Cmnd *)tmp->host_scribble;
tmp = (Scsi_Cmnd *) tmp->host_scribble;
}
/*
......@@ -1755,8 +1734,7 @@ unsigned long timeout;
if (hostdata->connected == cmd) {
printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ",
instance->host_no, cmd->pid);
printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->pid);
printk("sending wd33c93 ABORT command - ");
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
......@@ -1772,8 +1750,7 @@ unsigned long timeout;
read_3393(hostdata, WD_DATA);
} while (!(asr & ASR_INT) && timeout-- > 0);
sr = read_3393(hostdata, WD_SCSI_STATUS);
printk("asr=%02x, sr=%02x, %ld bytes un-transferred (timeout=%ld) - ",
asr, sr, read_3393_count(hostdata), timeout);
printk("asr=%02x, sr=%02x, %ld bytes un-transferred (timeout=%ld) - ", asr, sr, read_3393_count(hostdata), timeout);
/*
* Abort command processed.
......@@ -1789,7 +1766,7 @@ unsigned long timeout;
while ((asr & ASR_CIP) && timeout-- > 0)
asr = READ_AUX_STAT();
sr = read_3393(hostdata, WD_SCSI_STATUS);
printk("asr=%02x, sr=%02x.",asr,sr);
printk("asr=%02x, sr=%02x.", asr, sr);
hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
hostdata->connected = NULL;
......@@ -1797,9 +1774,9 @@ unsigned long timeout;
cmd->result = DID_ABORT << 16;
cmd->scsi_done(cmd);
in2000_execute (instance);
in2000_execute(instance);
return SCSI_ABORT_SUCCESS;
return SUCCESS;
}
/*
......@@ -1808,10 +1785,8 @@ unsigned long timeout;
* an ABORT_SNOOZE and hope for the best...
*/
for (tmp=(Scsi_Cmnd *)hostdata->disconnected_Q; tmp;
tmp=(Scsi_Cmnd *)tmp->host_scribble)
for (tmp = (Scsi_Cmnd *) hostdata->disconnected_Q; tmp; tmp = (Scsi_Cmnd *) tmp->host_scribble)
if (cmd == tmp) {
spin_unlock_irqrestore(instance->host_lock, flags);
printk(KERN_DEBUG "scsi%d: unable to abort disconnected command.\n", instance->host_no);
return FAILED;
}
......@@ -1826,11 +1801,9 @@ unsigned long timeout;
* broke.
*/
in2000_execute (instance);
in2000_execute(instance);
spin_unlock_irqrestore(instance->host_lock, flags);
printk("scsi%d: warning : SCSI command probably completed successfully"
" before abortion. ", instance->host_no);
printk("scsi%d: warning : SCSI command probably completed successfully" " before abortion. ", instance->host_no);
return SUCCESS;
}
......@@ -1843,12 +1816,12 @@ static char setup_buffer[SETUP_BUFFER_SIZE];
static char setup_used[MAX_SETUP_ARGS];
static int done_setup = 0;
static void __init in2000_setup (char *str, int *ints)
static void __init in2000_setup(char *str, int *ints)
{
int i;
char *p1,*p2;
int i;
char *p1, *p2;
strncpy(setup_buffer,str,SETUP_BUFFER_SIZE);
strncpy(setup_buffer, str, SETUP_BUFFER_SIZE);
setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0';
p1 = setup_buffer;
i = 0;
......@@ -1860,13 +1833,12 @@ char *p1,*p2;
setup_args[i] = p1;
p1 = p2 + 1;
i++;
}
else {
} else {
setup_args[i] = p1;
break;
}
}
for (i=0; i<MAX_SETUP_ARGS; i++)
for (i = 0; i < MAX_SETUP_ARGS; i++)
setup_used[i] = 0;
done_setup = 1;
}
......@@ -1877,10 +1849,10 @@ char *p1,*p2;
static int __init check_setup_args(char *key, int *flags, int *val, char *buf)
{
int x;
char *cp;
int x;
char *cp;
for (x=0; x<MAX_SETUP_ARGS; x++) {
for (x = 0; x < MAX_SETUP_ARGS; x++) {
if (setup_used[x])
continue;
if (!strncmp(setup_args[x], key, strlen(key)))
......@@ -1895,7 +1867,7 @@ char *cp;
return ++x;
cp++;
if ((*cp >= '0') && (*cp <= '9')) {
*val = simple_strtoul(cp,NULL,0);
*val = simple_strtoul(cp, NULL, 0);
}
return ++x;
}
......@@ -1912,36 +1884,36 @@ static u32 bios_tab[] in2000__INITDATA = {
0xd0000,
0xd8000,
0
};
};
static const unsigned short base_tab[] in2000__INITDATA = {
0x220,
0x200,
0x110,
0x100,
};
};
static const int int_tab[] in2000__INITDATA = {
15,
14,
11,
10
};
};
static int __init in2000_detect(Scsi_Host_Template * tpnt)
{
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
int detect_count;
int bios;
int x;
unsigned short base;
uchar switches;
uchar hrev;
int flags;
int val;
char buf[32];
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
int detect_count;
int bios;
int x;
unsigned short base;
uchar switches;
uchar hrev;
int flags;
int val;
char buf[32];
/* Thanks to help from Bill Earnest, probing for IN2000 cards is a
* pretty straightforward and fool-proof operation. There are 3
......@@ -1956,14 +1928,14 @@ char buf[32];
*/
if (!done_setup && setup_strings)
in2000_setup(setup_strings,0);
in2000_setup(setup_strings, 0);
detect_count = 0;
for (bios = 0; bios_tab[bios]; bios++) {
if (check_setup_args("ioport",&flags,&val,buf)) {
if (check_setup_args("ioport", &flags, &val, buf)) {
base = val;
switches = ~inb(base + IO_SWITCHES) & 0xff;
printk("Forcing IN2000 detection at IOport 0x%x ",base);
printk("Forcing IN2000 detection at IOport 0x%x ", base);
bios = 2;
}
/*
......@@ -1971,13 +1943,12 @@ char buf[32];
* for the obvious ID strings. We look for the 2 most common ones and
* hope that they cover all the cases...
*/
else if (isa_readl(bios_tab[bios]+0x10) == 0x41564f4e ||
isa_readl(bios_tab[bios]+0x30) == 0x61776c41) {
printk("Found IN2000 BIOS at 0x%x ",(unsigned int)bios_tab[bios]);
else if (isa_readl(bios_tab[bios] + 0x10) == 0x41564f4e || isa_readl(bios_tab[bios] + 0x30) == 0x61776c41) {
printk("Found IN2000 BIOS at 0x%x ", (unsigned int) bios_tab[bios]);
/* Read the switch image that's mapped into EPROM space */
switches = ~((isa_readb(bios_tab[bios]+0x20) & 0xff));
switches = ~((isa_readb(bios_tab[bios] + 0x20) & 0xff));
/* Find out where the IO space is */
......@@ -1988,17 +1959,16 @@ char buf[32];
x = ~inb(base + IO_SWITCHES) & 0xff;
if (x != switches) {
printk("Bad IO signature: %02x vs %02x.\n",x,switches);
printk("Bad IO signature: %02x vs %02x.\n", x, switches);
continue;
}
}
else
} else
continue;
/* OK. We have a base address for the IO ports - run a few safety checks */
if (!(switches & SW_BIT7)) { /* I _think_ all cards do this */
printk("There is no IN-2000 SCSI card at IOport 0x%03x!\n",base);
printk("There is no IN-2000 SCSI card at IOport 0x%03x!\n", base);
continue;
}
......@@ -2011,7 +1981,7 @@ char buf[32];
/* Bit 2 tells us if interrupts are disabled */
if (switches & SW_DISINT) {
printk("The IN-2000 SCSI card at IOport 0x%03x ",base);
printk("The IN-2000 SCSI card at IOport 0x%03x ", base);
printk("is not configured for interrupt operation!\n");
printk("This driver requires an interrupt: cancelling detection.\n");
continue;
......@@ -2023,19 +1993,17 @@ char buf[32];
tpnt->proc_name = "in2000";
instance = scsi_register(tpnt, sizeof(struct IN2000_hostdata));
if(instance == NULL)
if (instance == NULL)
continue;
detect_count++;
if (!instance_list)
instance_list = instance;
hostdata = (struct IN2000_hostdata *)instance->hostdata;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
instance->io_port = hostdata->io_base = base;
hostdata->dip_switch = switches;
hostdata->hrev = hrev;
write1_io(0,IO_FIFO_WRITE); /* clear fifo counter */
write1_io(0,IO_FIFO_READ); /* start fifo out in read mode */
write1_io(0,IO_INTR_MASK); /* allow all ints */
write1_io(0, IO_FIFO_WRITE); /* clear fifo counter */
write1_io(0, IO_FIFO_READ); /* start fifo out in read mode */
write1_io(0, IO_INTR_MASK); /* allow all ints */
x = int_tab[(switches & (SW_INT0 | SW_INT1)) >> SW_INT_SHIFT];
if (request_irq(x, in2000_intr, SA_INTERRUPT, "in2000", instance)) {
printk("in2000_detect: Unable to allocate IRQ.\n");
......@@ -2048,7 +2016,7 @@ char buf[32];
for (x = 0; x < 8; x++) {
hostdata->busy[x] = 0;
hostdata->sync_xfer[x] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
hostdata->sync_xfer[x] = calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF);
hostdata->sync_stat[x] = SS_UNSET; /* using default sync values */
#ifdef PROC_STATISTICS
hostdata->cmd_cnt[x] = 0;
......@@ -2071,44 +2039,42 @@ char buf[32];
/* Older BIOS's had a 'sync on/off' switch - use its setting */
if (isa_readl(bios_tab[bios]+0x10) == 0x41564f4e && (switches & SW_SYNC_DOS5))
if (isa_readl(bios_tab[bios] + 0x10) == 0x41564f4e && (switches & SW_SYNC_DOS5))
hostdata->sync_off = 0x00; /* sync defaults to on */
else
hostdata->sync_off = 0xff; /* sync defaults to off */
#ifdef PROC_INTERFACE
hostdata->proc = PR_VERSION|PR_INFO|PR_STATISTICS|
PR_CONNECTED|PR_INPUTQ|PR_DISCQ|
PR_STOP;
hostdata->proc = PR_VERSION | PR_INFO | PR_STATISTICS | PR_CONNECTED | PR_INPUTQ | PR_DISCQ | PR_STOP;
#ifdef PROC_STATISTICS
hostdata->int_cnt = 0;
#endif
#endif
if (check_setup_args("nosync",&flags,&val,buf))
if (check_setup_args("nosync", &flags, &val, buf))
hostdata->sync_off = val;
if (check_setup_args("period",&flags,&val,buf))
hostdata->default_sx_per = sx_table[round_period((unsigned int)val)].period_ns;
if (check_setup_args("period", &flags, &val, buf))
hostdata->default_sx_per = sx_table[round_period((unsigned int) val)].period_ns;
if (check_setup_args("disconnect",&flags,&val,buf)) {
if (check_setup_args("disconnect", &flags, &val, buf)) {
if ((val >= DIS_NEVER) && (val <= DIS_ALWAYS))
hostdata->disconnect = val;
else
hostdata->disconnect = DIS_ADAPTIVE;
}
if (check_setup_args("noreset",&flags,&val,buf))
if (check_setup_args("noreset", &flags, &val, buf))
hostdata->args ^= A_NO_SCSI_RESET;
if (check_setup_args("level2",&flags,&val,buf))
if (check_setup_args("level2", &flags, &val, buf))
hostdata->level2 = val;
if (check_setup_args("debug",&flags,&val,buf))
if (check_setup_args("debug", &flags, &val, buf))
hostdata->args = (val & DB_MASK);
#ifdef PROC_INTERFACE
if (check_setup_args("proc",&flags,&val,buf))
if (check_setup_args("proc", &flags, &val, buf))
hostdata->proc = val;
#endif
......@@ -2116,39 +2082,29 @@ char buf[32];
/* FIXME: not strictly needed I think but the called code expects
to be locked */
spin_lock_irqsave(instance->host_lock, flags);
x = reset_hardware(instance,(hostdata->args & A_NO_SCSI_RESET)?RESET_CARD:RESET_CARD_AND_BUS);
x = reset_hardware(instance, (hostdata->args & A_NO_SCSI_RESET) ? RESET_CARD : RESET_CARD_AND_BUS);
spin_unlock_irqrestore(instance->host_lock, flags);
hostdata->microcode = read_3393(hostdata,WD_CDB_1);
hostdata->microcode = read_3393(hostdata, WD_CDB_1);
if (x & 0x01) {
if (x & B_FLAG)
hostdata->chip = C_WD33C93B;
else
hostdata->chip = C_WD33C93A;
}
else
} else
hostdata->chip = C_WD33C93;
printk("dip_switch=%02x irq=%d ioport=%02x floppy=%s sync/DOS5=%s ",
(switches & 0x7f),
instance->irq,hostdata->io_base,
(switches & SW_FLOPPY)?"Yes":"No",
(switches & SW_SYNC_DOS5)?"Yes":"No");
printk("hardware_ver=%02x chip=%s microcode=%02x\n",
hrev,
(hostdata->chip==C_WD33C93)?"WD33c93":
(hostdata->chip==C_WD33C93A)?"WD33c93A":
(hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown",
hostdata->microcode);
printk("dip_switch=%02x irq=%d ioport=%02x floppy=%s sync/DOS5=%s ", (switches & 0x7f), instance->irq, hostdata->io_base, (switches & SW_FLOPPY) ? "Yes" : "No", (switches & SW_SYNC_DOS5) ? "Yes" : "No");
printk("hardware_ver=%02x chip=%s microcode=%02x\n", hrev, (hostdata->chip == C_WD33C93) ? "WD33c93" : (hostdata->chip == C_WD33C93A) ? "WD33c93A" : (hostdata->chip == C_WD33C93B) ? "WD33c93B" : "unknown", hostdata->microcode);
#ifdef DEBUGGING_ON
printk("setup_args = ");
for (x=0; x<MAX_SETUP_ARGS; x++)
printk("%s,",setup_args[x]);
for (x = 0; x < MAX_SETUP_ARGS; x++)
printk("%s,", setup_args[x]);
printk("\n");
#endif
if (hostdata->sync_off == 0xff)
printk("Sync-transfer DISABLED on all devices: ENABLE from command-line\n");
printk("IN2000 driver version %s - %s\n",IN2000_VERSION,IN2000_DATE);
printk("IN2000 driver version %s - %s\n", IN2000_VERSION, IN2000_DATE);
}
return detect_count;
......@@ -2163,17 +2119,14 @@ static int in2000_release(struct Scsi_Host *shost)
return 0;
}
/* NOTE: I lifted this function straight out of the old driver,
* and have not tested it. Presumably it does what it's
* supposed to do...
*/
static int in2000_biosparam(struct scsi_device *sdev,
struct block_device *bdev,
sector_t capacity, int *iinfo)
static int in2000_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *iinfo)
{
int size;
int size;
size = capacity;
iinfo[0] = 64;
......@@ -2187,17 +2140,17 @@ int size;
if (iinfo[2] > 1024) {
iinfo[0] = 64;
iinfo[1] = 63;
iinfo[2] = (unsigned long)capacity / (iinfo[0] * iinfo[1]);
iinfo[2] = (unsigned long) capacity / (iinfo[0] * iinfo[1]);
}
if (iinfo[2] > 1024) {
iinfo[0] = 128;
iinfo[1] = 63;
iinfo[2] = (unsigned long)capacity / (iinfo[0] * iinfo[1]);
iinfo[2] = (unsigned long) capacity / (iinfo[0] * iinfo[1]);
}
if (iinfo[2] > 1024) {
iinfo[0] = 255;
iinfo[1] = 63;
iinfo[2] = (unsigned long)capacity / (iinfo[0] * iinfo[1]);
iinfo[2] = (unsigned long) capacity / (iinfo[0] * iinfo[1]);
}
return 0;
}
......@@ -2208,21 +2161,21 @@ static int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn,
#ifdef PROC_INTERFACE
char *bp;
char tbuf[128];
unsigned long flags;
struct Scsi_Host *instance;
struct IN2000_hostdata *hd;
Scsi_Cmnd *cmd;
int x,i;
static int stop = 0;
char *bp;
char tbuf[128];
unsigned long flags;
struct Scsi_Host *instance;
struct IN2000_hostdata *hd;
Scsi_Cmnd *cmd;
int x, i;
static int stop = 0;
instance = scsi_host_hn_get(hn);
if (!instance) {
printk("*** Hmm... Can't find host #%d!\n",hn);
printk("*** Hmm... Can't find host #%d!\n", hn);
return (-ESRCH);
}
hd = (struct IN2000_hostdata *)instance->hostdata;
hd = (struct IN2000_hostdata *) instance->hostdata;
/* If 'in' is TRUE we need to _read_ the proc file. We accept the following
* keywords (same format as command-line, but only ONE per read):
......@@ -2236,36 +2189,31 @@ static int stop = 0;
if (in) {
buf[len] = '\0';
bp = buf;
if (!strncmp(bp,"debug:",6)) {
if (!strncmp(bp, "debug:", 6)) {
bp += 6;
hd->args = simple_strtoul(bp,NULL,0) & DB_MASK;
}
else if (!strncmp(bp,"disconnect:",11)) {
hd->args = simple_strtoul(bp, NULL, 0) & DB_MASK;
} else if (!strncmp(bp, "disconnect:", 11)) {
bp += 11;
x = simple_strtoul(bp,NULL,0);
x = simple_strtoul(bp, NULL, 0);
if (x < DIS_NEVER || x > DIS_ALWAYS)
x = DIS_ADAPTIVE;
hd->disconnect = x;
}
else if (!strncmp(bp,"period:",7)) {
} else if (!strncmp(bp, "period:", 7)) {
bp += 7;
x = simple_strtoul(bp,NULL,0);
hd->default_sx_per = sx_table[round_period((unsigned int)x)].period_ns;
}
else if (!strncmp(bp,"resync:",7)) {
x = simple_strtoul(bp, NULL, 0);
hd->default_sx_per = sx_table[round_period((unsigned int) x)].period_ns;
} else if (!strncmp(bp, "resync:", 7)) {
bp += 7;
x = simple_strtoul(bp,NULL,0);
for (i=0; i<7; i++)
if (x & (1<<i))
x = simple_strtoul(bp, NULL, 0);
for (i = 0; i < 7; i++)
if (x & (1 << i))
hd->sync_stat[i] = SS_UNSET;
}
else if (!strncmp(bp,"proc:",5)) {
} else if (!strncmp(bp, "proc:", 5)) {
bp += 5;
hd->proc = simple_strtoul(bp,NULL,0);
}
else if (!strncmp(bp,"level2:",7)) {
hd->proc = simple_strtoul(bp, NULL, 0);
} else if (!strncmp(bp, "level2:", 7)) {
bp += 7;
hd->level2 = simple_strtoul(bp,NULL,0);
hd->level2 = simple_strtoul(bp, NULL, 0);
}
return len;
}
......@@ -2274,81 +2222,74 @@ static int stop = 0;
bp = buf;
*bp = '\0';
if (hd->proc & PR_VERSION) {
sprintf(tbuf,"\nVersion %s - %s. Compiled %s %s",
IN2000_VERSION,IN2000_DATE,__DATE__,__TIME__);
strcat(bp,tbuf);
sprintf(tbuf, "\nVersion %s - %s. Compiled %s %s", IN2000_VERSION, IN2000_DATE, __DATE__, __TIME__);
strcat(bp, tbuf);
}
if (hd->proc & PR_INFO) {
sprintf(tbuf,"\ndip_switch=%02x: irq=%d io=%02x floppy=%s sync/DOS5=%s",
(hd->dip_switch & 0x7f), instance->irq, hd->io_base,
(hd->dip_switch & 0x40)?"Yes":"No",
(hd->dip_switch & 0x20)?"Yes":"No");
strcat(bp,tbuf);
strcat(bp,"\nsync_xfer[] = ");
for (x=0; x<7; x++) {
sprintf(tbuf,"\t%02x",hd->sync_xfer[x]);
strcat(bp,tbuf);
}
strcat(bp,"\nsync_stat[] = ");
for (x=0; x<7; x++) {
sprintf(tbuf,"\t%02x",hd->sync_stat[x]);
strcat(bp,tbuf);
sprintf(tbuf, "\ndip_switch=%02x: irq=%d io=%02x floppy=%s sync/DOS5=%s", (hd->dip_switch & 0x7f), instance->irq, hd->io_base, (hd->dip_switch & 0x40) ? "Yes" : "No", (hd->dip_switch & 0x20) ? "Yes" : "No");
strcat(bp, tbuf);
strcat(bp, "\nsync_xfer[] = ");
for (x = 0; x < 7; x++) {
sprintf(tbuf, "\t%02x", hd->sync_xfer[x]);
strcat(bp, tbuf);
}
strcat(bp, "\nsync_stat[] = ");
for (x = 0; x < 7; x++) {
sprintf(tbuf, "\t%02x", hd->sync_stat[x]);
strcat(bp, tbuf);
}
}
#ifdef PROC_STATISTICS
if (hd->proc & PR_STATISTICS) {
strcat(bp,"\ncommands issued: ");
for (x=0; x<7; x++) {
sprintf(tbuf,"\t%ld",hd->cmd_cnt[x]);
strcat(bp,tbuf);
strcat(bp, "\ncommands issued: ");
for (x = 0; x < 7; x++) {
sprintf(tbuf, "\t%ld", hd->cmd_cnt[x]);
strcat(bp, tbuf);
}
strcat(bp,"\ndisconnects allowed:");
for (x=0; x<7; x++) {
sprintf(tbuf,"\t%ld",hd->disc_allowed_cnt[x]);
strcat(bp,tbuf);
strcat(bp, "\ndisconnects allowed:");
for (x = 0; x < 7; x++) {
sprintf(tbuf, "\t%ld", hd->disc_allowed_cnt[x]);
strcat(bp, tbuf);
}
strcat(bp,"\ndisconnects done: ");
for (x=0; x<7; x++) {
sprintf(tbuf,"\t%ld",hd->disc_done_cnt[x]);
strcat(bp,tbuf);
strcat(bp, "\ndisconnects done: ");
for (x = 0; x < 7; x++) {
sprintf(tbuf, "\t%ld", hd->disc_done_cnt[x]);
strcat(bp, tbuf);
}
sprintf(tbuf,"\ninterrupts: \t%ld",hd->int_cnt);
strcat(bp,tbuf);
sprintf(tbuf, "\ninterrupts: \t%ld", hd->int_cnt);
strcat(bp, tbuf);
}
#endif
if (hd->proc & PR_CONNECTED) {
strcat(bp,"\nconnected: ");
strcat(bp, "\nconnected: ");
if (hd->connected) {
cmd = (Scsi_Cmnd *)hd->connected;
sprintf(tbuf," %ld-%d:%d(%02x)",
cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
strcat(bp,tbuf);
cmd = (Scsi_Cmnd *) hd->connected;
sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
strcat(bp, tbuf);
}
}
if (hd->proc & PR_INPUTQ) {
strcat(bp,"\ninput_Q: ");
cmd = (Scsi_Cmnd *)hd->input_Q;
strcat(bp, "\ninput_Q: ");
cmd = (Scsi_Cmnd *) hd->input_Q;
while (cmd) {
sprintf(tbuf," %ld-%d:%d(%02x)",
cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
strcat(bp,tbuf);
cmd = (Scsi_Cmnd *)cmd->host_scribble;
sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
strcat(bp, tbuf);
cmd = (Scsi_Cmnd *) cmd->host_scribble;
}
}
if (hd->proc & PR_DISCQ) {
strcat(bp,"\ndisconnected_Q:");
cmd = (Scsi_Cmnd *)hd->disconnected_Q;
strcat(bp, "\ndisconnected_Q:");
cmd = (Scsi_Cmnd *) hd->disconnected_Q;
while (cmd) {
sprintf(tbuf," %ld-%d:%d(%02x)",
cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
strcat(bp,tbuf);
cmd = (Scsi_Cmnd *)cmd->host_scribble;
sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
strcat(bp, tbuf);
cmd = (Scsi_Cmnd *) cmd->host_scribble;
}
}
if (hd->proc & PR_TEST) {
; /* insert your own custom function here */
}
strcat(bp,"\n");
strcat(bp, "\n");
spin_unlock_irqrestore(instance->host_lock, flags);
*start = buf;
if (stop) {
......@@ -2374,4 +2315,3 @@ MODULE_LICENSE("GPL");
static Scsi_Host_Template driver_template = IN2000;
#include "scsi_module.c"
......@@ -25,7 +25,7 @@
***********************************************************************/
/* $Id: nsp_cs.c,v 1.4 2002/10/15 15:57:01 elca Exp $ */
/* $Id: nsp_cs.c,v 1.5 2002/11/05 12:06:29 elca Exp $ */
#ifdef NSP_KERNEL_2_2
#include <pcmcia/config.h>
......@@ -67,7 +67,7 @@
#include "nsp_cs.h"
MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.4 $");
MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.5 $");
MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
......@@ -77,7 +77,7 @@ MODULE_LICENSE("GPL");
static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i");
MODULE_PARM_DESC(pc_debug, "set debug level");
static char *version = "$Id: nsp_cs.c,v 1.4 2002/10/15 15:57:01 elca Exp $";
static char *version = "$Id: nsp_cs.c,v 1.5 2002/11/05 12:06:29 elca Exp $";
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
#else
#define DEBUG(n, args...) /* */
......@@ -129,39 +129,30 @@ MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0
/* /usr/src/linux/drivers/scsi/hosts.h */
static Scsi_Host_Template driver_template = {
/* .next = NULL,*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
.proc_name = "nsp_cs", /* kernel 2.4 */
#else
.proc_dir = &proc_scsi_nsp, /* kernel 2.2 */
#endif
.proc_info = nsp_proc_info,
.name = "WorkBit NinjaSCSI-3/32Bi",
.name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
.detect = nsp_detect,
.release = nsp_release,
.info = nsp_info,
/* .command = NULL,*/
.queuecommand = nsp_queuecommand,
/* .eh_strategy_handler = nsp_eh_strategy,*/
/* .eh_abort_handler = nsp_eh_abort,*/
/* .eh_device_reset_handler = nsp_eh_device_reset,*/
.eh_bus_reset_handler = nsp_eh_bus_reset,
.eh_host_reset_handler = nsp_eh_host_reset,
.abort = nsp_abort,
.reset = nsp_reset,
/* .slave_attach = NULL,*/
/* .bios_param = NULL,*/
.can_queue = 1,
.this_id = NSP_INITIATOR_ID,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
/* .present = 0,*/
/* .unchecked_isa_dma = 0,*/
.use_clustering = DISABLE_CLUSTERING,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
.use_new_eh_code = 1,
#endif
/* .emulated = 0,*/
};
static dev_link_t *dev_list = NULL;
......@@ -180,12 +171,12 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
#endif
nsp_hw_data *data = &nsp_data;
DEBUG(0, "%s() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d\n",
DEBUG(0, "%s: SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d\n",
__FUNCTION__, SCpnt, target, SCpnt->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
//DEBUG(0, " before CurrentSC=0x%p\n", data->CurrentSC);
if(data->CurrentSC != NULL) {
printk(KERN_DEBUG " %s() CurrentSC!=NULL cannot happen!\n", __FUNCTION__);
printk(KERN_DEBUG " %s: CurrentSC!=NULL this can't be happen\n", __FUNCTION__);
data->CurrentSC = NULL;
SCpnt->result = DID_BAD_TARGET << 16;
done(SCpnt);
......@@ -231,7 +222,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
}
//DEBUG(0, __func__ "() out\n");
//DEBUG(0, "%s: out\n", __FUNCTION__);
return 0;
}
......@@ -243,7 +234,7 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
unsigned int base = data->BaseAddress;
unsigned char transfer_mode_reg;
//DEBUG(0, __func__ "() enabled=%d\n", enabled);
//DEBUG(0, "%s: enabled=%d\n", __FUNCTION__, enabled);
if (enabled != FALSE) {
transfer_mode_reg = TRANSFER_GO | BRAIND;
......@@ -265,7 +256,7 @@ static void nsphw_init_sync(nsp_hw_data *data)
int i;
/* setup sync data */
for ( i = 0; i < N_TARGET; i++ ) {
for ( i = 0; i < NUMBER(data->Sync); i++ ) {
data->Sync[i] = tmp_sync;
}
}
......@@ -277,7 +268,7 @@ static int nsphw_init(nsp_hw_data *data)
{
unsigned int base = data->BaseAddress;
DEBUG(0, "%s() in base=0x%x\n", __FUNCTION__, base);
DEBUG(0, "%s: in base=0x%x\n", __FUNCTION__, base);
data->ScsiClockDiv = CLOCK_40M | FAST_20;
data->CurrentSC = NULL;
......@@ -340,7 +331,7 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
int time_out;
unsigned char phase, arbit;
//DEBUG(0, __func__ "()in\n");
//DEBUG(0, "%s:in\n", __FUNCTION__);
phase = nsp_index_read(base, SCSIBUSMON);
if(phase != BUSMON_BUS_FREE) {
......@@ -422,7 +413,7 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
int i;
DEBUG(0, "%s()\n", __FUNCTION__);
DEBUG(0, "%s:\n", __FUNCTION__);
period = sync->SyncPeriod;
offset = sync->SyncOffset;
......@@ -473,7 +464,7 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time)
{
unsigned int base = SCpnt->host->io_port;
//DEBUG(0, __func__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time);
//DEBUG(0, "%s: in SCpnt=0x%p, time=%d\n", __FUNCTION__, SCpnt, time);
data->TimerCount = time;
nsp_index_write(base, TIMERCOUNT, time);
}
......@@ -487,7 +478,7 @@ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
unsigned char reg;
int time_out;
//DEBUG(0, __func__ "()\n");
//DEBUG(0, "%s:\n", __FUNCTION__);
time_out = 100;
......@@ -499,7 +490,7 @@ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
} while ((time_out-- != 0) && (reg & mask) != 0);
if (time_out == 0) {
printk(KERN_DEBUG "%s: %s signal off timeut\n", __FUNCTION__, str);
printk(KERN_DEBUG "%s:: %s signal off timeut\n", __FUNCTION__, str);
}
return 0;
......@@ -516,7 +507,7 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
int time_out;
unsigned char phase, i_src;
//DEBUG(0, __func__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask);
//DEBUG(0, "%s: current_phase=0x%x, mask=0x%x\n", __FUNCTION__, current_phase, mask);
time_out = 100;
do {
......@@ -536,7 +527,7 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
}
} while(time_out-- != 0);
//DEBUG(0, __func__ " : " __func__ " timeout\n");
//DEBUG(0, "%s: timeout\n", __FUNCTION__);
return -1;
}
......@@ -551,7 +542,7 @@ static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase)
int ptr;
int ret;
//DEBUG(0, __func__ "()\n");
//DEBUG(0, "%s:\n", __FUNCTION__);
for (ptr = 0; len > 0; len --, ptr ++) {
ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
......@@ -586,7 +577,7 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned int count;
//DEBUG(0, __func__ "()\n");
//DEBUG(0, "%s:\n", __FUNCTION__);
if (SCpnt->SCp.have_data_in != IO_IN) {
return 0;
......@@ -618,7 +609,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
unsigned int base = SCpnt->host->io_port;
unsigned char reg;
//DEBUG(0, __func__ "()\n");
//DEBUG(0, "%s:\n", __FUNCTION__);
nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
......@@ -648,7 +639,7 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
count = (h << 16) | (m << 8) | (l << 0);
//DEBUG(0, __func__ "() =0x%x\n", count);
//DEBUG(0, "%s: =0x%x\n", __FUNCTION__, count);
return count;
}
......@@ -670,7 +661,7 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
ocount = data->FifoCount;
DEBUG(0, "%s() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d\n",
DEBUG(0, "%s: in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d\n",
__FUNCTION__, SCpnt, RESID, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
time_out = 1000;
......@@ -744,7 +735,7 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
data->FifoCount = ocount;
if (time_out == 0) {
printk(KERN_DEBUG "%s() pio read timeout resid=%d this_residual=%d buffers_residual=%d\n",
printk(KERN_DEBUG "%s: pio read timeout resid=%d this_residual=%d buffers_residual=%d\n",
__FUNCTION__, RESID, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
}
DEBUG(0, " read ocount=0x%x\n", ocount);
......@@ -763,7 +754,8 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
ocount = data->FifoCount;
DEBUG(0, "%s() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x\n", __FUNCTION__, data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, RESID);
DEBUG(0, "%s: in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x\n",
__FUNCTION__, data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, RESID);
time_out = 1000;
......@@ -833,7 +825,7 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
data->FifoCount = ocount;
if (time_out == 0) {
printk(KERN_DEBUG "%s() pio write timeout resid=0x%x\n", __FUNCTION__, RESID);
printk(KERN_DEBUG "%s: pio write timeout resid=0x%x\n", __FUNCTION__, RESID);
}
DEBUG(0, " write ocount=0x%x\n", ocount);
}
......@@ -851,7 +843,7 @@ static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
// unsigned char lun = SCpnt->lun;
sync_data *sync = &(data->Sync[target]);
//DEBUG(0, __func__ "() in SCpnt=0x%p\n", SCpnt);
//DEBUG(0, "%s: in SCpnt=0x%p\n", __FUNCTION__, SCpnt);
/* setup synch transfer registers */
nsp_index_write(base, SYNCREG, sync->SyncRegister);
......@@ -948,7 +940,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
if (data->CurrentSC == NULL) {
printk(KERN_DEBUG "%s: CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x cannot happen\n", __FUNCTION__, i_src, phase, irq_phase);
printk(KERN_DEBUG "%s: CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen\n", __FUNCTION__, i_src, phase, irq_phase);
return;
} else {
tmpSC = data->CurrentSC;
......@@ -962,7 +954,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
*/
if ((i_src & IRQSTATUS_SCSI) != 0) {
if ((irq_phase & SCSI_RESET_IRQ) != 0) {
printk(KERN_DEBUG " %s() bus reset (power off?)\n", __FUNCTION__);
printk(KERN_DEBUG " %s: bus reset (power off?)\n", __FUNCTION__);
*sync_neg = SYNC_NOT_YET;
data->CurrentSC = NULL;
tmpSC->result = (DID_RESET << 16) |
......@@ -1064,7 +1056,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
/* check unexpected bus free state */
if (phase == 0) {
printk(KERN_DEBUG "%s: unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", __FUNCTION__, i_src, phase, irq_phase);
printk(KERN_DEBUG " %s: unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", __FUNCTION__, i_src, phase, irq_phase);
*sync_neg = SYNC_NOT_YET;
data->CurrentSC = NULL;
......@@ -1208,7 +1200,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
break;
}
//DEBUG(0, __func__ "() out\n");
//DEBUG(0, "%s: out\n", __FUNCTION__);
return;
timer_out:
......@@ -1246,7 +1238,7 @@ static int nsp_detect(Scsi_Host_Template *sht)
snprintf(data->nspinfo,
sizeof(data->nspinfo),
"NinjaSCSI-3/32Bi Driver $Revision: 1.4 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
"NinjaSCSI-3/32Bi Driver $Revision: 1.5 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
host->io_port, host->io_port + host->n_io_port - 1,
host->base,
host->irq);
......@@ -1303,16 +1295,28 @@ static int nsp_proc_info(char *buffer,
int speed;
unsigned long flags;
nsp_hw_data *data = &nsp_data;
struct Scsi_Host *host;
struct Scsi_Host *host = NULL;
if (inout) {
return -EINVAL;
}
/* search this HBA host */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45))
host = scsi_host_hn_get(hostno);
#else
for (host=scsi_hostlist; host; host=host->next) {
if (host->host_no == hostno) {
break;
}
}
#endif
if (host == NULL) {
return -ESRCH;
}
SPRINTF("NinjaSCSI status\n\n");
SPRINTF("Driver version: $Revision: 1.4 $\n");
SPRINTF("Driver version: $Revision: 1.5 $\n");
SPRINTF("SCSI host No.: %d\n", hostno);
SPRINTF("IRQ: %d\n", host->irq);
SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
......@@ -1393,45 +1397,6 @@ static int nsp_proc_info(char *buffer,
}
#undef SPRINTF
/*---------------------------------------------------------------*/
/* error handler */
/*---------------------------------------------------------------*/
static int nsp_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
{
nsp_hw_data *data = &nsp_data;
int ret = 0;
DEBUG(0, "%s: SCpnt=0x%p why=%d\n", __FUNCTION__, SCpnt, reset_flags);
if (reset_flags & SCSI_RESET_SUGGEST_BUS_RESET) {
nsp_eh_bus_reset(SCpnt);
ret |= SCSI_RESET_BUS_RESET;
}
if (reset_flags & SCSI_RESET_SUGGEST_HOST_RESET) {
nsp_eh_host_reset(SCpnt);
ret |= SCSI_RESET_HOST_RESET;
}
if (ret != 0) {
return SCSI_RESET_SUCCESS | ret;
} else {
nsphw_init_sync(data);
return SCSI_RESET_PUNT;
}
}
static int nsp_abort(Scsi_Cmnd *SCpnt)
{
DEBUG(0, "%s: SCpnt=0x%p\n", __FUNCTION__, SCpnt);
nsp_eh_host_reset(SCpnt);
nsp_eh_bus_reset(SCpnt);
return SCSI_ABORT_SUCCESS;
}
/*static int nsp_eh_strategy(struct Scsi_Host *Shost)
{
......@@ -1460,7 +1425,7 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
unsigned int base = SCpnt->host->io_port;
int i;
DEBUG(0, "%s() SCpnt=0x%p base=0x%x\n", __FUNCTION__, SCpnt, base);
DEBUG(0, "%s: SCpnt=0x%p base=0x%x\n", __FUNCTION__, SCpnt, base);
nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
......@@ -1482,7 +1447,7 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
{
nsp_hw_data *data = &nsp_data;
DEBUG(0, "%s\n", __FUNCTION__);
DEBUG(0, "%s:\n", __FUNCTION__);
nsphw_init(data);
......@@ -1517,7 +1482,7 @@ static dev_link_t *nsp_cs_attach(void)
dev_link_t *link;
int ret, i;
DEBUG(0, "%s()\n", __FUNCTION__);
DEBUG(0, "%s:\n", __FUNCTION__);
/* Create new SCSI device */
info = kmalloc(sizeof(*info), GFP_KERNEL);
......@@ -1607,7 +1572,7 @@ static void nsp_cs_detach(dev_link_t *link)
return;
}
del_timer_sync(&link->release);
del_timer(&link->release);
if (link->state & DEV_CONFIG) {
nsp_cs_release((u_long)link);
if (link->state & DEV_STALE_CONFIG) {
......@@ -1659,7 +1624,7 @@ static void nsp_cs_config(dev_link_t *link)
nsp_hw_data *data = &nsp_data;
DEBUG(0, "%s() in\n", __FUNCTION__);
DEBUG(0, "%s: in\n", __FUNCTION__);
tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
......@@ -1764,7 +1729,7 @@ static void nsp_cs_config(dev_link_t *link)
break;
next_entry:
DEBUG(0, "%s next\n", __FUNCTION__);
DEBUG(0, "%s: next\n", __FUNCTION__);
if (link->io.NumPorts1)
CardServices(ReleaseIO, link->handle, &link->io);
......@@ -1787,9 +1752,8 @@ static void nsp_cs_config(dev_link_t *link)
data->NumAddress = link->io.NumPorts1;
data->IrqNumber = link->irq.AssignedIRQ;
DEBUG(0, "%s I/O[0x%x+0x%x] IRQ %d\n",
__FUNCTION__,
data->BaseAddress, data->NumAddress, data->IrqNumber);
DEBUG(0, "%s: I/O[0x%x+0x%x] IRQ %d\n",
__FUNCTION__, data->BaseAddress, data->NumAddress, data->IrqNumber);
if(nsphw_init(data) == FALSE) {
goto cs_failed;
......@@ -1804,8 +1768,13 @@ static void nsp_cs_config(dev_link_t *link)
DEBUG(0, "GET_SCSI_INFO\n");
tail = &link->dev;
info->ndev = 0;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45))
for (host = scsi_host_get_next(NULL); host;
host = scsi_host_get_next(host)) {
#else
for (host = scsi_hostlist; host != NULL; host = host->next) {
#endif
if (host->hostt == &driver_template) {
for (dev = host->host_queue; dev != NULL; dev = dev->next) {
u_long arg[2], id;
......@@ -1998,7 +1967,7 @@ static int nsp_cs_event(event_t event,
DEBUG(0, " event: unknown\n");
break;
}
DEBUG(0, "%s end\n", __FUNCTION__);
DEBUG(0, "%s: end\n", __FUNCTION__);
return 0;
} /* nsp_cs_event */
......@@ -2009,7 +1978,7 @@ static int __init nsp_cs_init(void)
{
servinfo_t serv;
DEBUG(0, "%s() in\n", __FUNCTION__);
DEBUG(0, "%s: in\n", __FUNCTION__);
DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
......@@ -2019,14 +1988,14 @@ static int __init nsp_cs_init(void)
}
register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
DEBUG(0, "%s() out\n", __FUNCTION__);
DEBUG(0, "%s: out\n", __FUNCTION__);
return 0;
}
static void __exit nsp_cs_cleanup(void)
{
DEBUG(0, "%s() unloading\n", __FUNCTION__);
DEBUG(0, "%s: unloading\n", __FUNCTION__);
unregister_pcmcia_driver(&dev_info);
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG) {
......
......@@ -10,7 +10,7 @@
=========================================================*/
/* $Id: nsp_cs.h,v 1.3 2002/10/10 11:07:52 elca Exp $ */
/* $Id: nsp_cs.h,v 1.4 2002/11/05 12:06:29 elca Exp $ */
#ifndef __nsp_cs__
#define __nsp_cs__
......@@ -26,7 +26,7 @@
/************************************
* Some useful macros...
*/
#define Number(arr) ((int) (sizeof(arr) / sizeof(arr[0])))
#define NUMBER(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) /* from XtNumber() in /usr/X11R6/include/X11/Intrinsic.h */
#define BIT(x) (1L << (x))
#define MIN(a,b) ((a) > (b) ? (b) : (a))
......@@ -285,9 +285,6 @@ static int nsp_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout);
static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
static int nsp_abort(Scsi_Cmnd *);
static int nsp_reset(Scsi_Cmnd *, unsigned int);
/*static int nsp_eh_abort(Scsi_Cmnd * SCpnt);*/
/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt);
......
......@@ -64,7 +64,7 @@ static void nsp_message_out(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
DEBUG(0, " msgout loop\n");
do {
if (nsp_xfer(SCpnt, data, BUSPHASE_MESSAGE_OUT)) {
printk(KERN_DEBUG " %s msgout: xfer short\n", __FUNCTION__);
printk(KERN_DEBUG " %s: msgout: xfer short\n", __FUNCTION__);
}
/* catch a next signal */
......
......@@ -613,7 +613,7 @@ int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
#ifdef PCMCIA
/*
* Allow PCMCIA code to preset the port */
* Allow PCMCIA code to preset the port
* port should be 0 and irq to -1 respectively for autoprobing
*/
......
......@@ -1486,16 +1486,16 @@ static int u14_34f_eh_host_reset(Scsi_Cmnd *SCarg) {
return SUCCESS;
}
static int u14_34f_bios_param(Disk *disk, struct block_device *bdev,
int *dkinfo) {
static int u14_34f_bios_param(struct scsi_device *disk, struct block_device *bdev,
sector_t capacity, int *dkinfo) {
unsigned int j = 0;
int size = disk->capacity;
unsigned int size = capacity;
dkinfo[0] = HD(j)->heads;
dkinfo[1] = HD(j)->sectors;
dkinfo[2] = size / (HD(j)->heads * HD(j)->sectors);
if (ext_tran && (scsicam_bios_param(disk, bdev, dkinfo) < 0)) {
if (ext_tran && (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
dkinfo[0] = 255;
dkinfo[1] = 63;
dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
......
......@@ -7,7 +7,7 @@ static int u14_34f_release(struct Scsi_Host *);
static int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int u14_34f_eh_abort(Scsi_Cmnd *);
static int u14_34f_eh_host_reset(Scsi_Cmnd *);
static int u14_34f_bios_param(Disk *, struct block_device *, int *);
static int u14_34f_bios_param(struct scsi_device *, struct block_device *, sector_t, int *);
static int u14_34f_slave_attach(Scsi_Device *);
#define U14_34F_VERSION "8.00.00"
......@@ -17,8 +17,6 @@ static int u14_34f_slave_attach(Scsi_Device *);
detect: u14_34f_detect, \
release: u14_34f_release, \
queuecommand: u14_34f_queuecommand, \
abort: NULL, \
reset: NULL, \
eh_abort_handler: u14_34f_eh_abort, \
eh_device_reset_handler: NULL, \
eh_bus_reset_handler: NULL, \
......
......@@ -8,6 +8,9 @@
* John's work modified by Caleb Epstein (cae@jpmorgan.com) and
* Eric Youngdale (ericy@cais.com).
* Thanks to UltraStor for providing the necessary documentation
*
* This is an old driver, for the 14F and 34F you should be using the
* u14-34f driver instead.
*/
/*
......@@ -164,8 +167,8 @@
packed structure. */
typedef struct {
unsigned int address;
unsigned int num_bytes;
u32 address;
u32 num_bytes;
} ultrastor_sg_list;
......@@ -190,7 +193,7 @@ struct mscp {
unsigned char scsi_cdbs[12]; /* SCSI commands */
unsigned char adapter_status; /* non-zero indicates HA error */
unsigned char target_status; /* non-zero indicates target error */
unsigned int sense_data PACKED;
u32 sense_data PACKED;
/* The following fields are for software only. They are included in
the MSCP structure because they are associated with SCSI requests. */
void (*done)(Scsi_Cmnd *);
......@@ -289,17 +292,15 @@ static void do_ultrastor_interrupt(int, void *, struct pt_regs *);
static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt);
/* Always called with host lock held */
static inline int find_and_clear_bit_16(unsigned short *field)
{
int rv;
unsigned long flags;
save_flags(flags);
cli();
if (*field == 0) panic("No free mscp");
asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b"
: "=&r" (rv), "=m" (*field) : "1" (*field));
restore_flags(flags);
return rv;
}
......@@ -320,14 +321,12 @@ static inline unsigned char xchgb(unsigned char reg,
#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
static void log_ultrastor_abort(register struct ultrastor_config *config,
/* Always called with the host lock held */
static void log_ultrastor_abort(struct ultrastor_config *config,
int command)
{
static char fmt[80] = "abort %d (%x); MSCP free pool: %x;";
register int i;
unsigned long flags;
save_flags(flags);
cli();
int i;
for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
{
......@@ -340,7 +339,7 @@ static void log_ultrastor_abort(register struct ultrastor_config *config,
fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n';
fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0;
printk(fmt, command, &config->mscp[command], config->mscp_free);
restore_flags(flags);
}
#endif
......@@ -528,7 +527,7 @@ static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
{
register int i;
int i;
struct Scsi_Host * shpnt = NULL;
#if (ULTRASTOR_DEBUG & UD_DETECT)
......@@ -638,13 +637,13 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
return FALSE;
}
int ultrastor_detect(Scsi_Host_Template * tpnt)
static int ultrastor_detect(Scsi_Host_Template * tpnt)
{
tpnt->proc_name = "ultrastor";
return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
}
const char *ultrastor_info(struct Scsi_Host * shpnt)
static const char *ultrastor_info(struct Scsi_Host * shpnt)
{
static char buf[64];
......@@ -662,7 +661,7 @@ const char *ultrastor_info(struct Scsi_Host * shpnt)
return buf;
}
static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
static inline void build_sg_list(struct mscp *mscp, Scsi_Cmnd *SCpnt)
{
struct scatterlist *sl;
long transfer_length = 0;
......@@ -683,14 +682,13 @@ static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
mscp->transfer_data_length = transfer_length;
}
int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
static int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
register struct mscp *my_mscp;
struct mscp *my_mscp;
#if ULTRASTOR_MAX_CMDS > 1
int mscp_index;
#endif
unsigned int status;
unsigned long flags;
/* Next test is for debugging; "can't happen" */
if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
......@@ -706,14 +704,8 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
my_mscp = &config.mscp[mscp_index];
#if 1
/* This way is faster. */
*(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
#else
my_mscp->opcode = OP_SCSI;
my_mscp->xdir = DTD_SCSI;
my_mscp->dcn = FALSE;
#endif
/* Tape drives don't work properly if the cache is used. The SCSI
READ command for a tape doesn't have a block offset, and the adapter
incorrectly assumes that all reads from the tape read the same
......@@ -748,35 +740,31 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->host_scribble = (unsigned char *)my_mscp;
/* Find free OGM slot. On 24F, look for OGM status byte == 0.
On 14F and 34F, wait for local interrupt pending flag to clear. */
On 14F and 34F, wait for local interrupt pending flag to clear.
retry:
FIXME: now we are using new_eh we should punt here and let the
midlayer sort it out */
retry:
if (config.slot)
while (inb(config.ogm_address - 1) != 0 &&
config.aborted[mscp_index] == 0xff) barrier();
while (inb(config.ogm_address - 1) != 0 && config.aborted[mscp_index] == 0xff)
barrier();
/* else??? */
while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
(config.slot ? 2 : 1))
&& config.aborted[mscp_index] == 0xff) barrier();
/* To avoid race conditions, make the code to write to the adapter
atomic. This simplifies the abort code. */
while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) & (config.slot ? 2 : 1)) && config.aborted[mscp_index] == 0xff)
barrier();
save_flags(flags);
cli();
/* To avoid race conditions, keep the code to write to the adapter
atomic. This simplifies the abort code. Right now the
scsi mid layer has the host_lock already held
*/
if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
(config.slot ? 2 : 1))
{
restore_flags(flags);
if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) & (config.slot ? 2 : 1))
goto retry;
}
status = xchgb(0, &config.aborted[mscp_index]);
if (status != 0xff) {
restore_flags(flags);
#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
printk("USx4F: queuecommand: aborted\n");
......@@ -811,8 +799,6 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
}
restore_flags(flags);
#if (ULTRASTOR_DEBUG & UD_COMMAND)
printk("USx4F: queuecommand: returning\n");
#endif
......@@ -835,7 +821,7 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
*/
int ultrastor_abort(Scsi_Cmnd *SCpnt)
static int ultrastor_abort(Scsi_Cmnd *SCpnt)
{
#if ULTRASTOR_DEBUG & UD_ABORT
char out[108];
......@@ -844,14 +830,16 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
#endif
unsigned int mscp_index;
unsigned char old_aborted;
unsigned long flags;
void (*done)(Scsi_Cmnd *);
struct Scsi_Host *host = SCpnt->host;
if(config.slot)
return SCSI_ABORT_SNOOZE; /* Do not attempt an abort for the 24f */
return FAILED; /* Do not attempt an abort for the 24f */
/* Simple consistency checking */
if(!SCpnt->host_scribble)
return SCSI_ABORT_NOT_RUNNING;
return FAILED;
mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
if (mscp_index >= ULTRASTOR_MAX_CMDS)
......@@ -863,8 +851,8 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
int port0 = (config.slot << 12) | 0xc80;
int i;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(host->host_lock, flags);
strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
for (i = 0; i < 16; i++)
{
......@@ -879,7 +867,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
ogm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 23));
icm_status = inb(port0 + 27);
icm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 28));
restore_flags(flags);
spin_lock_irqsave(host->host_lock, flags);
}
/* First check to see if an interrupt is pending. I suspect the SiS
......@@ -888,14 +876,13 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
if (config.slot ? inb(config.icm_address - 1) == 2 :
(inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
{
unsigned long flags;
save_flags(flags);
printk("Ux4F: abort while completed command pending\n");
restore_flags(flags);
cli();
spin_lock_irqsave(host->host_lock, flags);
/* FIXME: Ewww... need to think about passing host around properly */
ultrastor_interrupt(0, NULL, NULL);
restore_flags(flags);
return SCSI_ABORT_SUCCESS; /* FIXME - is this correct? -ERY */
spin_unlock_irqrestore(host->host_lock, flags);
return SUCCESS;
}
#endif
......@@ -904,7 +891,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
/* aborted == 0xff is the signal that queuecommand has not yet sent
the command. It will notice the new abort flag and fail. */
if (old_aborted == 0xff)
return SCSI_ABORT_SUCCESS;
return SUCCESS;
/* On 24F, send an abort MSCP request. The adapter will interrupt
and the interrupt handler will call done. */
......@@ -912,18 +899,18 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
{
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(host->host_lock, flags);
outl(isa_virt_to_bus(&config.mscp[mscp_index]), config.ogm_address);
inb(0xc80); /* delay */
udelay(8);
outb(0x80, config.ogm_address - 1);
outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
#if ULTRASTOR_DEBUG & UD_ABORT
log_ultrastor_abort(&config, mscp_index);
printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
#endif
restore_flags(flags);
return SCSI_ABORT_PENDING;
spin_unlock_irqrestore(host->host_lock, flags);
/* FIXME: add a wait for the abort to complete */
return SUCCESS;
}
#if ULTRASTOR_DEBUG & UD_ABORT
......@@ -953,27 +940,30 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
done = config.mscp[mscp_index].done;
config.mscp[mscp_index].done = 0;
SCpnt->result = DID_ABORT << 16;
/* I worry about reentrancy in scsi.c */
/* Take the host lock to guard against scsi layer re-entry */
spin_lock_irqsave(host->host_lock, flags);
done(SCpnt);
spin_unlock_irqrestore(host->host_lock, flags);
/* Need to set a timeout here in case command never completes. */
return SCSI_ABORT_SUCCESS;
return SUCCESS;
}
int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
static int ultrastor_host_reset(Scsi_Cmnd * SCpnt)
{
unsigned long flags;
register int i;
int i;
struct Scsi_Host *host = SCpnt->host;
#if (ULTRASTOR_DEBUG & UD_RESET)
printk("US14F: reset: called\n");
#endif
if(config.slot)
return SCSI_RESET_PUNT; /* Do not attempt a reset for the 24f */
save_flags(flags);
cli();
return FAILED;
spin_lock_irqsave(host->host_lock, flags);
/* Reset the adapter and SCSI bus. The SCSI bus reset can be
inhibited by clearing ultrastor_bus_reset before probe. */
outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
......@@ -1005,7 +995,10 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
#endif
/* FIXME - if the device implements soft resets, then the command
will still be running. ERY */
will still be running. ERY
Even bigger deal with new_eh!
*/
memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
#if ULTRASTOR_MAX_CMDS == 1
......@@ -1014,7 +1007,7 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
config.mscp_free = ~0;
#endif
restore_flags(flags);
spin_unlock_irqrestore(host->host_lock, flags);
return SCSI_RESET_SUCCESS;
}
......@@ -1041,7 +1034,7 @@ static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if ULTRASTOR_MAX_CMDS > 1
unsigned int mscp_index;
#endif
register struct mscp *mscp;
struct mscp *mscp;
void (*done)(Scsi_Cmnd *);
Scsi_Cmnd *SCtmp;
......
......@@ -13,13 +13,12 @@
#ifndef _ULTRASTOR_H
#define _ULTRASTOR_H
int ultrastor_detect(Scsi_Host_Template *);
const char *ultrastor_info(struct Scsi_Host * shpnt);
int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int ultrastor_abort(Scsi_Cmnd *);
int ultrastor_reset(Scsi_Cmnd *, unsigned int);
int ultrastor_biosparam(struct scsi_device *, struct block_device *,
sector_t, int *);
static int ultrastor_detect(Scsi_Host_Template *);
static const char *ultrastor_info(struct Scsi_Host * shpnt);
static int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int ultrastor_abort(Scsi_Cmnd *);
static int ultrastor_host_reset(Scsi_Cmnd *);
static int ultrastor_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
#define ULTRASTOR_14F_MAX_SG 16
......@@ -35,8 +34,8 @@ int ultrastor_biosparam(struct scsi_device *, struct block_device *,
detect: ultrastor_detect, \
info: ultrastor_info, \
queuecommand: ultrastor_queuecommand, \
abort: ultrastor_abort, \
reset: ultrastor_reset, \
eh_abort_handler: ultrastor_abort, \
eh_host_reset_handler: ultrastor_host_reset, \
bios_param: ultrastor_biosparam, \
can_queue: ULTRASTOR_MAX_CMDS, \
this_id: 0, \
......
......@@ -1240,7 +1240,7 @@ static int wd7000_adapter_reset(Adapter * host)
host->control = 0; /* this must always shadow ASC_CONTROL */
if (WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
printk("wd7000_init: WAIT timed out.\n");
printk(KERN_ERR "wd7000_init: WAIT timed out.\n");
return -1; /* -1 = not ok */
}
......@@ -1249,25 +1249,25 @@ static int wd7000_adapter_reset(Adapter * host)
switch (diag) {
case 2:
printk("RAM failure.\n");
printk(KERN_ERR "RAM failure.\n");
break;
case 3:
printk("FIFO R/W failed\n");
printk(KERN_ERR "FIFO R/W failed\n");
break;
case 4:
printk("SBIC register R/W failed\n");
printk(KERN_ERR "SBIC register R/W failed\n");
break;
case 5:
printk("Initialization D-FF failed.\n");
printk(KERN_ERR "Initialization D-FF failed.\n");
break;
case 6:
printk("Host IRQ D-FF failed.\n");
printk(KERN_ERR "Host IRQ D-FF failed.\n");
break;
case 7:
printk("ROM checksum error.\n");
printk(KERN_ERR "ROM checksum error.\n");
break;
default:
printk("diagnostic code 0x%02Xh received.\n", diag);
printk(KERN_ERR "diagnostic code 0x%02Xh received.\n", diag);
}
return -1;
}
......
......@@ -74,7 +74,7 @@
#ifdef CONFIG_FS_EXT_ATTR
# include <linux/ext_attr.h>
# ifdef CONFIG_FS_POSIX_ACL
# if 0 /* was a broken check for Posix ACLs */
# include <linux/posix_acl.h>
# endif
#endif
......@@ -466,7 +466,7 @@ int lento_setattr(const char *name, struct iattr *iattr,
struct dentry *dentry;
struct presto_file_set *fset;
int error;
#ifdef CONFIG_FS_POSIX_ACL
#if 0 /* was a broken check for Posix ACLs */
int (*set_posix_acl)(struct inode *, int type, posix_acl_t *)=NULL;
#endif
......@@ -507,7 +507,7 @@ int lento_setattr(const char *name, struct iattr *iattr,
(dentry->d_inode->i_mode & ~S_IALLUGO);
CDEBUG(D_PIOCTL, "chmod: orig %#o, set %#o, result %#o\n",
dentry->d_inode->i_mode, set_mode, iattr->ia_mode);
#ifdef CONFIG_FS_POSIX_ACL
#if 0 /* was a broken check for Posix ACLs */
/* ACl code interacts badly with setattr
* since it tries to modify the ACL using
* set_ext_attr which recurses back into presto.
......@@ -535,7 +535,7 @@ int lento_setattr(const char *name, struct iattr *iattr,
}
}
#ifdef CONFIG_FS_POSIX_ACL
#if 0 /* was a broken check for Posix ACLs */
/* restore the inode_operations if we changed them*/
if (iattr->ia_valid & ATTR_MODE)
dentry->d_inode->i_op->set_posix_acl=set_posix_acl;
......@@ -2252,7 +2252,7 @@ int lento_iopen(const char *name, ino_t ino, unsigned int generation,
#ifdef CONFIG_FS_EXT_ATTR
#ifdef CONFIG_FS_POSIX_ACL
#if 0 /* was a broken check for Posix ACLs */
/* Posix ACL code changes i_mode without using a notify_change (or
* a mark_inode_dirty!). We need to duplicate this at the reintegrator
* which is done by this function. This function also takes care of
......@@ -2395,7 +2395,7 @@ int presto_do_set_ext_attr(struct presto_file_set *fset,
goto exit;
}
#ifdef CONFIG_FS_POSIX_ACL
#if 0 /* was a broken check for Posix ACLs */
/* Reset mode if specified*/
/* XXX: when we do native acl support, move this code out! */
if (mode != NULL) {
......
......@@ -1401,6 +1401,7 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l)
inode = filp->f_dentry->d_inode;
#ifdef CONFIG_MMU
/* Don't allow mandatory locks on files that may be memory mapped
* and shared.
*/
......@@ -1413,6 +1414,7 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l)
goto out;
}
}
#endif
error = flock_to_posix_lock(filp, file_lock, &flock);
if (error)
......
......@@ -97,7 +97,7 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) \
&& !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) \
&& !defined(__arm__)
&& !defined(__arm__) && !defined(CONFIG_V850)
/*
* For backward compatibility? Maybe this should be moved
......
......@@ -19,4 +19,8 @@ struct timer_opts{
#define TICK_SIZE (tick_nsec / 1000)
extern struct timer_opts* select_timer(void);
/* Modifiers for buggy PIT handling */
extern int pit_latch_buggy;
#endif
......@@ -17,8 +17,8 @@ config CRC32
#
config ZLIB_INFLATE
tristate
default m if CRAMFS!=y && PPP_DEFLATE!=y && JFFS2_FS!=y && ZISOFS_FS!=y && (CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m)
default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y
default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y
default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m
config ZLIB_DEFLATE
tristate
......
......@@ -11,6 +11,6 @@ $(obj)/initramfs_data.o: $(src)/initramfs_data.scr $(obj)/initramfs_data.cpio.gz
$(call if_changed,ld)
$(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio
( cd $(obj) ; ./$< | gzip -9c > $@ )
./$< | gzip -9c > $@
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment