Commit 91076e50 authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

Merge ssh://mulgrave-w/BK/scsi-misc-2.5

into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5
parents d55b3076 9273e16f
This diff is collapsed.
This diff is collapsed.
...@@ -48,25 +48,35 @@ cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-falign-functions=0 -falign-jumps ...@@ -48,25 +48,35 @@ cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-falign-functions=0 -falign-jumps
CFLAGS += $(cflags-y) CFLAGS += $(cflags-y)
ifdef CONFIG_VISWS #default subarch .c files
MACHINE := mach-visws mcore-y := mach-default
else
MACHINE := mach-generic #VISWS subarch support
endif mflags-$(CONFIG_VISWS) := -Iinclude/asm-i386/mach-visws
mcore-$(CONFIG_VISWS) := mach-visws
#NUMAQ subarch support
mflags-$(CONFIG_X86_NUMAQ) := -Iinclude/asm-i386/mach-numaq
mcore-$(CONFIG_X86_NUMAQ) := mach-default
#add other subarch support here
#default subarch .h files
mflags-y += -Iinclude/asm-i386/mach-default
HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
libs-y += arch/i386/lib/ libs-y += arch/i386/lib/
core-y += arch/i386/kernel/ \ core-y += arch/i386/kernel/ \
arch/i386/mm/ \ arch/i386/mm/ \
arch/i386/$(MACHINE)/ arch/i386/$(mcore-y)/
drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/ drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/
drivers-$(CONFIG_PCI) += arch/i386/pci/ drivers-$(CONFIG_PCI) += arch/i386/pci/
# FIXME: is drivers- right ? # FIXME: is drivers- right ?
drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/ drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/
CFLAGS += -Iarch/i386/$(MACHINE) CFLAGS += $(mflags-y)
AFLAGS += -Iarch/i386/$(MACHINE) AFLAGS += $(mflags-y)
makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/i386/boot $(1) makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/i386/boot $(1)
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/arch_hooks.h> #include <asm/arch_hooks.h>
#include "mach_apic.h"
#include <mach_apic.h>
void __init apic_intr_init(void) void __init apic_intr_init(void)
{ {
...@@ -310,11 +311,9 @@ void __init setup_local_APIC (void) ...@@ -310,11 +311,9 @@ void __init setup_local_APIC (void)
__error_in_apic_c(); __error_in_apic_c();
/* /*
* Double-check wether this APIC is really registered. * Double-check whether this APIC is really registered.
* This is meaningless in clustered apic mode, so we skip it.
*/ */
if (!clustered_apic_mode && if (!apic_id_registered())
!test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
BUG(); BUG();
/* /*
...@@ -322,21 +321,7 @@ void __init setup_local_APIC (void) ...@@ -322,21 +321,7 @@ void __init setup_local_APIC (void)
* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
* document number 292116). So here it goes... * document number 292116). So here it goes...
*/ */
init_apic_ldr();
if (!clustered_apic_mode) {
/*
* In clustered apic mode, the firmware does this for us
* Put the APIC into flat delivery mode.
* Must be "all ones" explicitly for 82489DX.
*/
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
/*
* Set up the logical destination ID.
*/
value = apic_read(APIC_LDR);
apic_write_around(APIC_LDR, calculate_ldr(value));
}
/* /*
* Set Task Priority to 'accept all'. We never change this * Set Task Priority to 'accept all'. We never change this
......
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/desc.h> #include <asm/desc.h>
#include "mach_apic.h"
#include <mach_apic.h>
#undef APIC_LOCKUP_DEBUG #undef APIC_LOCKUP_DEBUG
...@@ -261,7 +262,7 @@ static inline void balance_irq(int irq) ...@@ -261,7 +262,7 @@ static inline void balance_irq(int irq)
irq_balance_t *entry = irq_balance + irq; irq_balance_t *entry = irq_balance + irq;
unsigned long now = jiffies; unsigned long now = jiffies;
if (clustered_apic_mode) if (no_balance_irq)
return; return;
if (unlikely(time_after(now, entry->timestamp + IRQ_BALANCE_INTERVAL))) { if (unlikely(time_after(now, entry->timestamp + IRQ_BALANCE_INTERVAL))) {
...@@ -739,7 +740,6 @@ void __init setup_IO_APIC_irqs(void) ...@@ -739,7 +740,6 @@ void __init setup_IO_APIC_irqs(void)
if (irq_trigger(idx)) { if (irq_trigger(idx)) {
entry.trigger = 1; entry.trigger = 1;
entry.mask = 1; entry.mask = 1;
entry.dest.logical.logical_dest = TARGET_CPUS;
} }
irq = pin_2_irq(idx, apic, pin); irq = pin_2_irq(idx, apic, pin);
...@@ -747,7 +747,7 @@ void __init setup_IO_APIC_irqs(void) ...@@ -747,7 +747,7 @@ void __init setup_IO_APIC_irqs(void)
* skip adding the timer int on secondary nodes, which causes * skip adding the timer int on secondary nodes, which causes
* a small but painful rift in the time-space continuum * a small but painful rift in the time-space continuum
*/ */
if (clustered_apic_mode && (apic != 0) && (irq == 0)) if (multi_timer_check(apic, irq))
continue; continue;
else else
add_pin_to_irq(irq, apic, pin); add_pin_to_irq(irq, apic, pin);
...@@ -1135,7 +1135,7 @@ void disable_IO_APIC(void) ...@@ -1135,7 +1135,7 @@ void disable_IO_APIC(void)
static void __init setup_ioapic_ids_from_mpc (void) static void __init setup_ioapic_ids_from_mpc (void)
{ {
struct IO_APIC_reg_00 reg_00; struct IO_APIC_reg_00 reg_00;
unsigned long phys_id_present_map = phys_cpu_present_map; unsigned long phys_id_present_map;
int apic; int apic;
int i; int i;
unsigned char old_id; unsigned char old_id;
...@@ -1145,9 +1145,8 @@ static void __init setup_ioapic_ids_from_mpc (void) ...@@ -1145,9 +1145,8 @@ static void __init setup_ioapic_ids_from_mpc (void)
/* This gets done during IOAPIC enumeration for ACPI. */ /* This gets done during IOAPIC enumeration for ACPI. */
return; return;
if (clustered_apic_mode) phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
/* We don't have a good way to do this yet - hack */
phys_id_present_map = (u_long) 0xf;
/* /*
* Set the IOAPIC ID to the value stored in the MPC table. * Set the IOAPIC ID to the value stored in the MPC table.
*/ */
......
...@@ -30,7 +30,9 @@ ...@@ -30,7 +30,9 @@
#include <asm/mpspec.h> #include <asm/mpspec.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#include "mach_apic.h"
#include <mach_apic.h>
#include <mach_mpparse.h>
/* Have we found an MP table */ /* Have we found an MP table */
int smp_found_config; int smp_found_config;
...@@ -103,28 +105,12 @@ static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdat ...@@ -103,28 +105,12 @@ static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdat
void __init MP_processor_info (struct mpc_config_processor *m) void __init MP_processor_info (struct mpc_config_processor *m)
{ {
int ver, quad, logical_apicid; int ver, apicid;
if (!(m->mpc_cpuflag & CPU_ENABLED)) if (!(m->mpc_cpuflag & CPU_ENABLED))
return; return;
logical_apicid = m->mpc_apicid; apicid = mpc_apic_id(m, translation_table[mpc_record]->trans_quad);
if (clustered_apic_mode) {
quad = translation_table[mpc_record]->trans_quad;
logical_apicid = (quad << 4) +
(m->mpc_apicid ? m->mpc_apicid << 1 : 1);
printk("Processor #%d %ld:%ld APIC version %d (quad %d, apic %d)\n",
m->mpc_apicid,
(m->mpc_cpufeature & CPU_FAMILY_MASK)>>8,
(m->mpc_cpufeature & CPU_MODEL_MASK)>>4,
m->mpc_apicver, quad, logical_apicid);
} else {
printk("Processor #%d %ld:%ld APIC version %d\n",
m->mpc_apicid,
(m->mpc_cpufeature & CPU_FAMILY_MASK)>>8,
(m->mpc_cpufeature & CPU_MODEL_MASK)>>4,
m->mpc_apicver);
}
if (m->mpc_featureflag&(1<<0)) if (m->mpc_featureflag&(1<<0))
Dprintk(" Floating point unit present.\n"); Dprintk(" Floating point unit present.\n");
...@@ -177,7 +163,7 @@ void __init MP_processor_info (struct mpc_config_processor *m) ...@@ -177,7 +163,7 @@ void __init MP_processor_info (struct mpc_config_processor *m)
if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
Dprintk(" Bootup CPU\n"); Dprintk(" Bootup CPU\n");
boot_cpu_physical_apicid = m->mpc_apicid; boot_cpu_physical_apicid = m->mpc_apicid;
boot_cpu_logical_apicid = logical_apicid; boot_cpu_logical_apicid = apicid;
} }
num_processors++; num_processors++;
...@@ -190,11 +176,8 @@ void __init MP_processor_info (struct mpc_config_processor *m) ...@@ -190,11 +176,8 @@ void __init MP_processor_info (struct mpc_config_processor *m)
} }
ver = m->mpc_apicver; ver = m->mpc_apicver;
if (clustered_apic_mode) { phys_cpu_present_map |= apicid_to_cpu_present(apicid);
phys_cpu_present_map |= (logical_apicid&0xf) << (4*quad);
} else {
phys_cpu_present_map |= apicid_to_cpu_present(m->mpc_apicid);
}
/* /*
* Validate version * Validate version
*/ */
...@@ -209,28 +192,18 @@ void __init MP_processor_info (struct mpc_config_processor *m) ...@@ -209,28 +192,18 @@ void __init MP_processor_info (struct mpc_config_processor *m)
static void __init MP_bus_info (struct mpc_config_bus *m) static void __init MP_bus_info (struct mpc_config_bus *m)
{ {
char str[7]; char str[7];
int quad;
memcpy(str, m->mpc_bustype, 6); memcpy(str, m->mpc_bustype, 6);
str[6] = 0; str[6] = 0;
if (clustered_apic_mode) { mpc_oem_bus_info(m, str, translation_table[mpc_record]);
quad = translation_table[mpc_record]->trans_quad;
mp_bus_id_to_node[m->mpc_busid] = quad;
mp_bus_id_to_local[m->mpc_busid] = translation_table[mpc_record]->trans_local;
printk("Bus #%d is %s (node %d)\n", m->mpc_busid, str, quad);
} else {
Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
}
if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
} else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
} else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) { } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
if (clustered_apic_mode){ mpc_oem_pci_bus(m, translation_table[mpc_record]);
quad_local_to_mp_bus_id[quad][translation_table[mpc_record]->trans_local] = m->mpc_busid;
}
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
mp_current_pci_id++; mp_current_pci_id++;
...@@ -318,6 +291,7 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \ ...@@ -318,6 +291,7 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \
int count = sizeof (*oemtable); /* the header size */ int count = sizeof (*oemtable); /* the header size */
unsigned char *oemptr = ((unsigned char *)oemtable)+count; unsigned char *oemptr = ((unsigned char *)oemtable)+count;
mpc_record = 0;
printk("Found an OEM MPC table at %8p - parsing it ... \n", oemtable); printk("Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4)) if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4))
{ {
...@@ -394,7 +368,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) ...@@ -394,7 +368,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
str[12]=0; str[12]=0;
printk("Product ID: %s ",str); printk("Product ID: %s ",str);
summit_check(oem, str); mps_oem_check(mpc, oem, str);
printk("APIC at: 0x%lX\n",mpc->mpc_lapic); printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
...@@ -405,16 +379,10 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) ...@@ -405,16 +379,10 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
if (!acpi_lapic) if (!acpi_lapic)
mp_lapic_addr = mpc->mpc_lapic; mp_lapic_addr = mpc->mpc_lapic;
if (clustered_apic_mode && mpc->mpc_oemptr) {
/* We need to process the oem mpc tables to tell us which quad things are in ... */
mpc_record = 0;
smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, mpc->mpc_oemsize);
mpc_record = 0;
}
/* /*
* Now process the configuration blocks. * Now process the configuration blocks.
*/ */
mpc_record = 0;
while (count < mpc->mpc_length) { while (count < mpc->mpc_length) {
switch(*mpt) { switch(*mpt) {
case MP_PROCESSOR: case MP_PROCESSOR:
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/smpboot.h> #include <asm/smpboot.h>
#include <mach_ipi.h>
/* /*
* Some notes on x86 processor bugs affecting SMP operation: * Some notes on x86 processor bugs affecting SMP operation:
...@@ -227,54 +228,6 @@ static inline void send_IPI_mask_sequence(int mask, int vector) ...@@ -227,54 +228,6 @@ static inline void send_IPI_mask_sequence(int mask, int vector)
local_irq_restore(flags); local_irq_restore(flags);
} }
static inline void send_IPI_mask(int mask, int vector)
{
if (clustered_apic_mode)
send_IPI_mask_sequence(mask, vector);
else
send_IPI_mask_bitmask(mask, vector);
}
static inline void send_IPI_allbutself(int vector)
{
/*
* if there are no other CPUs in the system then
* we get an APIC send error if we try to broadcast.
* thus we have to avoid sending IPIs in this case.
*/
if (!(num_online_cpus() > 1))
return;
if (clustered_apic_mode) {
// Pointless. Use send_IPI_mask to do this instead
int cpu;
for (cpu = 0; cpu < NR_CPUS; ++cpu) {
if (cpu_online(cpu) && cpu != smp_processor_id())
send_IPI_mask(1 << cpu, vector);
}
} else {
__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
return;
}
}
static inline void send_IPI_all(int vector)
{
if (clustered_apic_mode) {
// Pointless. Use send_IPI_mask to do this instead
int cpu;
for (cpu = 0; cpu < NR_CPUS; ++cpu) {
if (!cpu_online(cpu))
continue;
send_IPI_mask(1 << cpu, vector);
}
} else {
__send_IPI_shortcut(APIC_DEST_ALLINC, vector);
}
}
/* /*
* Smarter SMP flushing macros. * Smarter SMP flushing macros.
* c/o Linus Torvalds. * c/o Linus Torvalds.
......
...@@ -51,7 +51,8 @@ ...@@ -51,7 +51,8 @@
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/arch_hooks.h> #include <asm/arch_hooks.h>
#include "smpboot_hooks.h" #include "smpboot_hooks.h"
#include "mach_apic.h"
#include <mach_apic.h>
/* Set if we find a B stepping CPU */ /* Set if we find a B stepping CPU */
static int __initdata smp_b_stepping; static int __initdata smp_b_stepping;
...@@ -848,11 +849,7 @@ static void __init do_boot_cpu (int apicid) ...@@ -848,11 +849,7 @@ static void __init do_boot_cpu (int apicid)
/* /*
* Starting actual IPI sequence... * Starting actual IPI sequence...
*/ */
wakeup_secondary_cpu(apicid, start_eip);
if (clustered_apic_mode)
boot_error = wakeup_secondary_via_NMI(apicid);
else
boot_error = wakeup_secondary_via_INIT(apicid, start_eip);
if (!boot_error) { if (!boot_error) {
/* /*
...@@ -1060,15 +1057,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -1060,15 +1057,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid) if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid)
BUG(); BUG();
if (clustered_apic_mode && (numnodes > 1)) { setup_portio_remap();
printk("Remapping cross-quad port I/O for %d quads\n",
numnodes);
xquad_portio = ioremap (XQUAD_PORTIO_BASE,
numnodes * XQUAD_PORTIO_QUAD);
printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
(u_long) xquad_portio,
(u_long) numnodes * XQUAD_PORTIO_QUAD);
}
/* /*
* Scan the CPU present map and fire up the other CPUs via do_boot_cpu * Scan the CPU present map and fire up the other CPUs via do_boot_cpu
......
#ifndef __ASM_MACH_APIC_H
#define __ASM_MACH_APIC_H
static inline unsigned long calculate_ldr(unsigned long old)
{
unsigned long id;
id = 1UL << smp_processor_id();
return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id));
}
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
#ifdef CONFIG_SMP
#define TARGET_CPUS (clustered_apic_mode ? 0xf : cpu_online_map)
#else
#define TARGET_CPUS 0x01
#endif
#define APIC_BROADCAST_ID 0x0F
#define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid))
static inline void summit_check(char *oem, char *productid)
{
}
static inline void clustered_apic_check(void)
{
printk("Enabling APIC mode: %s. Using %d I/O APICs\n",
(clustered_apic_mode ? "NUMA-Q" : "Flat"), nr_ioapics);
}
static inline int cpu_present_to_apicid(int mps_cpu)
{
if (clustered_apic_mode)
return ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) );
else
return mps_cpu;
}
static inline unsigned long apicid_to_cpu_present(int apicid)
{
return (1ul << apicid);
}
#endif /* __ASM_MACH_APIC_H */
...@@ -277,15 +277,10 @@ config SCSI_AACRAID ...@@ -277,15 +277,10 @@ config SCSI_AACRAID
tristate "Adaptec AACRAID support (EXPERIMENTAL)" tristate "Adaptec AACRAID support (EXPERIMENTAL)"
depends on EXPERIMENTAL && SCSI && PCI depends on EXPERIMENTAL && SCSI && PCI
choice source "drivers/scsi/aic7xxx/Kconfig.aic7xxx"
prompt "Adaptec AIC7xxx support"
optional
depends on SCSI
source "drivers/scsi/aic7xxx/Kconfig"
config SCSI_AIC7XXX_OLD config SCSI_AIC7XXX_OLD
tristate "Old driver" tristate "Adaptec AIC7xxx support (old driver)"
help help
WARNING This driver is an older aic7xxx driver and is no longer WARNING This driver is an older aic7xxx driver and is no longer
under active development. Adaptec, Inc. is writing a new driver to under active development. Adaptec, Inc. is writing a new driver to
...@@ -325,8 +320,7 @@ config SCSI_AIC7XXX_OLD ...@@ -325,8 +320,7 @@ config SCSI_AIC7XXX_OLD
say M here and read <file:Documentation/modules.txt>. The module say M here and read <file:Documentation/modules.txt>. The module
will be called aic7xxx_old.o. will be called aic7xxx_old.o.
endchoice source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
# All the I2O code and drivers do not seem to be 64bit safe. # All the I2O code and drivers do not seem to be 64bit safe.
config SCSI_DPT_I2O config SCSI_DPT_I2O
......
config SCSI_AIC7XXX
tristate "New driver"
help
This driver supports all of Adaptec's PCI based SCSI controllers
(not the hardware RAID controllers though) as well as the aic7770
based EISA and VLB SCSI controllers (the 274x and 284x series).
This is an Adaptec sponsored driver written by Justin Gibbs. It is
intended to replace the previous aic7xxx driver maintained by Doug
Ledford since Doug is no longer maintaining that driver.
config AIC7XXX_CMDS_PER_DEVICE
int "Maximum number of TCQ commands per device"
depends on SCSI_AIC7XXX
default "253"
---help---
Specify the number of commands you would like to allocate per SCSI
device when Tagged Command Queueing (TCQ) is enabled on that device.
This is an upper bound value for the number of tagged transactions
to be used for any device. The aic7xxx driver will automatically
vary this number based on device behavior. For devices with a
fixed maximum, the driver will eventually lock to this maximum
and display a console message inidicating this value.
Note: Unless you experience some type of device failure, the default
value, no enforced limit, should work for you.
Default: 253
config AIC7XXX_RESET_DELAY_MS
int "Initial bus reset delay in milli-seconds"
depends on SCSI_AIC7XXX
default "15000"
help
The number of milliseconds to delay after an initial bus reset.
The bus settle delay following all error recovery actions is
dictated by the SCSI layer and is not affected by this value.
Default: 15000 (15 seconds)
config AIC7XXX_BUILD_FIRMWARE
bool "Build Adapter Firmware with Kernel Build"
depends on SCSI_AIC7XXX
help
This option should only be enabled if you are modifying the firmware
source to the aic7xxx driver and wish to have the generated firmware
include files updated during a normal kernel build. The assembler
for the firmware requires lex and yacc or their equivalents, as well
as the db v1 library. You may have to install additional packages
or modify the assembler make file or the files it includes if your
build environment is different than that of the author.
#
# AIC79XX 2.5.X Kernel configuration File.
# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic79xx#2 $
#
config SCSI_AIC79XX
tristate "Adaptec AIC79xx U320 support"
depends on PCI
help
This driver supports all of Adaptec's Ultra 320 PCI-X
based SCSI controllers.
config AIC79XX_CMDS_PER_DEVICE
int "Maximum number of TCQ commands per device"
depends on SCSI_AIC79XX
default "32"
---help---
Specify the number of commands you would like to allocate per SCSI
device when Tagged Command Queueing (TCQ) is enabled on that device.
This is an upper bound value for the number of tagged transactions
to be used for any device. The aic7xxx driver will automatically
vary this number based on device behavior. For devices with a
fixed maximum, the driver will eventually lock to this maximum
and display a console message inidicating this value.
Due to resource allocation issues in the Linux SCSI mid-layer, using
a high number of commands per device may result in memory allocation
failures when many devices are attached to the system. For this reason,
the default is set to 32. Higher values may result in higer performance
on some devices. The upper bound is 253. 0 disables tagged queueing.
Per device tag depth can be controlled via the kernel command line
"tag_info" option. See drivers/scsi/aic7xxx/README.aic79xx
for details.
config AIC79XX_RESET_DELAY_MS
int "Initial bus reset delay in milli-seconds"
depends on SCSI_AIC79XX
default "15000"
---help---
The number of milliseconds to delay after an initial bus reset.
The bus settle delay following all error recovery actions is
dictated by the SCSI layer and is not affected by this value.
Default: 15000 (15 seconds)
config AIC79XX_BUILD_FIRMWARE
bool "Build Adapter Firmware with Kernel Build"
depends on SCSI_AIC79XX
help
This option should only be enabled if you are modifying the firmware
source to the aic79xx driver and wish to have the generated firmware
include files updated during a normal kernel build. The assembler
for the firmware requires lex and yacc or their equivalents, as well
as the db v1 library. You may have to install additional packages
or modify the assembler Makefile or the files it includes if your
build environment is different than that of the author.
config AIC79XX_ENABLE_RD_STRM
bool "Enable Read Streaming for All Targets"
depends on SCSI_AIC79XX
help
Read Streaming is a U320 protocol option that should enhance
performance. Early U320 drive firmware actually performs slower
with read streaming enabled so it is disabled by default. Read
Streaming can be configured in much the same way as tagged queueing
using the "rd_strm" command line option. See
drivers/scsi/aic7xxx/README.aic79xx for details.
config AIC79XX_DEBUG_ENABLE
bool "Compile in Debugging Code"
depends on SCSI_AIC79XX
default y
help
Compile in aic79xx debugging code that can be useful in diagnosing
driver errors.
config AIC79XX_DEBUG_MASK
int "Debug code enable mask (16383 for all debugging)"
depends on SCSI_AIC79XX
default "0"
help
Bit mask of debug options that is only valid if the
CONFIG_AIC79XX_DEBUG_ENBLE option is enabled. The bits in this mask
are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the
variable ahd_debug in that file to find them.
config AIC79XX_REG_PRETTY_PRINT
bool "Decode registers during diagnostics"
depends on SCSI_AIC79XX
default y
help
Compile in register value tables for the output of expanded register
contents in diagnostics. This make it much easier to understand debug
output without having to refer to a data book and/or the aic7xxx.reg
file.
#
# AIC7XXX and AIC79XX 2.5.X Kernel configuration File.
# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#4 $
#
config SCSI_AIC7XXX
tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
---help---
This driver supports all of Adaptec's Fast through Ultra 160 PCI
based SCSI controllers as well as the aic7770 based EISA and VLB
SCSI controllers (the 274x and 284x series). For AAA and ARO based
configurations, only SCSI functionality is provided.
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called aic7xxx.o.
config AIC7XXX_CMDS_PER_DEVICE
int "Maximum number of TCQ commands per device"
depends on SCSI_AIC7XXX
default "32"
---help---
Specify the number of commands you would like to allocate per SCSI
device when Tagged Command Queueing (TCQ) is enabled on that device.
This is an upper bound value for the number of tagged transactions
to be used for any device. The aic7xxx driver will automatically
vary this number based on device behavior. For devices with a
fixed maximum, the driver will eventually lock to this maximum
and display a console message inidicating this value.
Due to resource allocation issues in the Linux SCSI mid-layer, using
a high number of commands per device may result in memory allocation
failures when many devices are attached to the system. For this reason,
the default is set to 32. Higher values may result in higer performance
on some devices. The upper bound is 253. 0 disables tagged queueing.
Per device tag depth can be controlled via the kernel command line
"tag_info" option. See drivers/scsi/aic7xxx/README.aic7xxx
for details.
config AIC7XXX_RESET_DELAY_MS
int "Initial bus reset delay in milli-seconds"
depends on SCSI_AIC7XXX
default "15000"
---help---
The number of milliseconds to delay after an initial bus reset.
The bus settle delay following all error recovery actions is
dictated by the SCSI layer and is not affected by this value.
Default: 15000 (15 seconds)
config AIC7XXX_PROBE_EISA_VL
bool "Probe for EISA and VL AIC7XXX Adapters"
help
Probe for EISA and VLB Aic7xxx controllers. In many newer systems,
the invasive probes necessary to detect these controllers can cause
other devices to fail. For this reason, the non-PCI probe code is
disabled by default. The current value of this option can be "toggled"
via the no_probe kernel command line option.
config AIC7XXX_BUILD_FIRMWARE
bool "Build Adapter Firmware with Kernel Build"
depends on SCSI_AIC7XXX
help
This option should only be enabled if you are modifying the firmware
source to the aic7xxx driver and wish to have the generated firmware
include files updated during a normal kernel build. The assembler
for the firmware requires lex and yacc or their equivalents, as well
as the db v1 library. You may have to install additional packages
or modify the assembler Makefile or the files it includes if your
build environment is different than that of the author.
config AIC7XXX_DEBUG_ENABLE
bool "Compile in Debugging Code"
depends on SCSI_AIC7XXX
default y
help
Compile in aic7xxx debugging code that can be useful in diagnosing
driver errors.
config AIC7XXX_DEBUG_MASK
int "Debug code enable mask (2047 for all debugging)"
depends on SCSI_AIC7XXX
default "0"
help
Bit mask of debug options that is only valid if the
CONFIG_AIC7XXX_DEBUG_ENBLE option is enabled. The bits in this mask
are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the
variable ahc_debug in that file to find them.
config AIC7XXX_REG_PRETTY_PRINT
bool "Decode registers during diagnostics"
depends on SCSI_AIC7XXX
default y
help
Compile in register value tables for the output of expanded register
contents in diagnostics. This make it much easier to understand debug
output without having to refer to a data book and/or the aic7xxx.reg
file.
# #
# Makefile for the Linux aic7xxx SCSI driver. # Makefile for the Linux aic7xxx SCSI driver.
# #
# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#3 $
#
# Let kbuild descend into aicasm when cleaning # Let kbuild descend into aicasm when cleaning
subdir- += aicasm subdir- += aicasm
obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o
obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o
# Core files # Core Fast -> U160 files
aic7xxx-objs += aic7xxx_core.o aic7xxx_93cx6.o aic7770.o aic7xxx-y += aic7xxx_core.o \
aic7xxx_93cx6.o \
aic7770.o
aic7xxx-$(CONFIG_PCI) += aic7xxx_pci.o
aic7xxx-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) += aic7xxx_reg_print.o
# Platform Specific Files # Platform Specific Fast -> U160 Files
aic7xxx-objs += aic7xxx_linux.o aic7xxx_proc.o aic7770_linux.o aic7xxx-y += aic7xxx_osm.o \
aic7xxx_proc.o \
aic7770_osm.o
aic7xxx-$(CONFIG_PCI) += aic7xxx_osm_pci.o
# PCI Specific Files # Core U320 files
ifeq ($(CONFIG_PCI),y) aic79xx-y += aic79xx_core.o \
# Core PCI files aic79xx_pci.o
aic7xxx-objs += aic7xxx_pci.o aic79xx-$(CONFIG_AIC79XX_REG_PRETTY_PRINT) += aic79xx_reg_print.o
# Platform Specific PCI Files
aic7xxx-objs += aic7xxx_linux_pci.o
endif
# Platform Specific U320 Files
aic79xx-y += aic79xx_osm.o \
aic79xx_proc.o \
aic79xx_osm_pci.o
EXTRA_CFLAGS += -Idrivers/scsi
#EXTRA_CFLAGS += -g #EXTRA_CFLAGS += -g
# Files generated that shall be removed upon make clean # Files generated that shall be removed upon make clean
clean-files := aic7xxx_seq.h aic7xxx_reg.h clean-files := aic7xxx_seq.h aic7xxx_reg.h aic7xxx_reg_print.c
clean-files += aic79xx_seq.h aic79xx_reg.h aic79xx_reg_print.c
# Dependencies for generated files need to be listed explicitly # Dependencies for generated files need to be listed explicitly
$(obj)/aic7xxx_core.o: $(obj)/aic7xxx_seq.h $(obj)/aic7xxx_core.o: $(obj)/aic7xxx_seq.h
$(obj)/aic79xx_core.o: $(obj)/aic79xx_seq.h
$(addprefix $(obj)/,$(aic7xxx-objs)): $(obj)/aic7xxx_reg.h $(addprefix $(obj)/,$(aic7xxx-y)): $(obj)/aic7xxx_reg.h
$(addprefix $(obj)/,$(aic79xx-y)): $(obj)/aic79xx_reg.h
ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y) ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
aic7xxx_gen = $(obj)/aic7xxx_seq.h $(obj)/aic7xxx_reg.h
ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y)
aic7xxx_gen += $(obj)/aic7xxx_reg_print.c
aic7xxx_asm_cmd = $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \
-p $(obj)/aic7xxx_reg_print.c -i aic7xxx_osm.h \
-o $(obj)/aic7xxx_seq.h $(src)/aic7xxx.seq
else
aic7xxx_asm_cmd = $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \
-o $(obj)/aic7xxx_seq.h $(src)/aic7xxx.seq
endif
$(obj)/aic7xxx_seq.h: $(src)/aic7xxx.seq $(src)/aic7xxx.reg \ $(aic7xxx_gen): $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm
$(obj)/aicasm/aicasm $(aic7xxx_asm_cmd)
$(obj)/aicasm/aicasm -I$(obj) -r $(obj)/aic7xxx_reg.h \ endif
-o $(obj)/aic7xxx_seq.h $(src)/aic7xxx.seq
$(obj)/aic7xxx_reg.h: $(obj)/aic7xxx_seq.h ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
aic79xx_gen = $(obj)/aic79xx_seq.h $(obj)/aic79xx_reg.h
ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y)
aic79xx_gen += $(obj)/aic79xx_reg_print.c
aic79xx_asm_cmd = $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \
-p $(obj)/aic79xx_reg_print.c -i aic79xx_osm.h \
-o $(obj)/aic79xx_seq.h $(src)/aic79xx.seq
else
aic79xx_asm_cmd = $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \
-o $(obj)/aic79xx_seq.h $(src)/aic79xx.seq
endif
$(aic79xx_gen): $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm
$(aic79xx_asm_cmd)
endif
$(obj)/aicasm/aicasm: $(src)/aicasm/*.[chyl] $(obj)/aicasm/aicasm: $(src)/aicasm/*.[chyl]
$(MAKE) -C $(src)/aicasm $(MAKE) -C $(src)/aicasm
endif
...@@ -37,22 +37,29 @@ ...@@ -37,22 +37,29 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7770.c#14 $ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#27 $
* *
* $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1 2000/09/16 20:02:27 gibbs Exp $ * $FreeBSD$
*/ */
#ifdef __linux__
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
#include "aic7xxx_inline.h" #include "aic7xxx_inline.h"
#include "aic7xxx_93cx6.h" #include "aic7xxx_93cx6.h"
#else
#include <dev/aic7xxx/aic7xxx_osm.h>
#include <dev/aic7xxx/aic7xxx_inline.h>
#include <dev/aic7xxx/aic7xxx_93cx6.h>
#endif
#define ID_AIC7770 0x04907770 #define ID_AIC7770 0x04907770
#define ID_AHA_274x 0x04907771 #define ID_AHA_274x 0x04907771
#define ID_AHA_284xB 0x04907756 /* BIOS enabled */ #define ID_AHA_284xB 0x04907756 /* BIOS enabled */
#define ID_AHA_284x 0x04907757 /* BIOS disabled*/ #define ID_AHA_284x 0x04907757 /* BIOS disabled*/
#define ID_AIC_7782 0x04907782 #define ID_OLV_274x 0x04907782 /* Olivetti OEM */
#define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */
static void aha2840_load_seeprom(struct ahc_softc *ahc); static int aha2840_load_seeprom(struct ahc_softc *ahc);
static ahc_device_setup_t ahc_aic7770_VL_setup; static ahc_device_setup_t ahc_aic7770_VL_setup;
static ahc_device_setup_t ahc_aic7770_EISA_setup;; static ahc_device_setup_t ahc_aic7770_EISA_setup;;
static ahc_device_setup_t ahc_aic7770_setup; static ahc_device_setup_t ahc_aic7770_setup;
...@@ -72,18 +79,23 @@ struct aic7770_identity aic7770_ident_table [] = ...@@ -72,18 +79,23 @@ struct aic7770_identity aic7770_ident_table [] =
"Adaptec 284X SCSI adapter", "Adaptec 284X SCSI adapter",
ahc_aic7770_VL_setup ahc_aic7770_VL_setup
}, },
/* Generic chip probes for devices we don't know 'exactly' */
{ {
ID_AIC7770, ID_OLV_274x,
0xFFFFFFFF, 0xFFFFFFFF,
"Adaptec aic7770 SCSI adapter", "Adaptec (Olivetti OEM) 274X SCSI adapter",
ahc_aic7770_EISA_setup ahc_aic7770_EISA_setup
}, },
{ {
/* (Olivetti 2 channel EISA) */ ID_OLV_274xD,
ID_AIC_7782,
0xFFFFFFFF, 0xFFFFFFFF,
"Adaptec aic7782 SCSI adapter", "Adaptec (Olivetti OEM) 274X Differential SCSI adapter",
ahc_aic7770_EISA_setup
},
/* Generic chip probes for devices we don't know 'exactly' */
{
ID_AIC7770,
0xFFFFFFFF,
"Adaptec aic7770 SCSI adapter",
ahc_aic7770_EISA_setup ahc_aic7770_EISA_setup
} }
}; };
...@@ -104,21 +116,32 @@ aic7770_find_device(uint32_t id) ...@@ -104,21 +116,32 @@ aic7770_find_device(uint32_t id)
} }
int int
aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry) aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
{ {
u_long l;
int error; int error;
int have_seeprom;
u_int hostconf; u_int hostconf;
u_int irq; u_int irq;
u_int intdef; u_int intdef;
error = entry->setup(ahc); error = entry->setup(ahc);
have_seeprom = 0;
if (error != 0) if (error != 0)
return (error); return (error);
error = aic7770_map_registers(ahc); error = aic7770_map_registers(ahc, io);
if (error != 0) if (error != 0)
return (error); return (error);
/*
* Before we continue probing the card, ensure that
* its interrupts are *disabled*. We don't want
* a misstep to hang the machine in an interrupt
* storm.
*/
ahc_intr_enable(ahc, FALSE);
ahc->description = entry->name; ahc->description = entry->name;
error = ahc_softc_init(ahc); error = ahc_softc_init(ahc);
...@@ -176,21 +199,22 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry) ...@@ -176,21 +199,22 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry)
ahc->flags |= AHC_TERM_ENB_B; ahc->flags |= AHC_TERM_ENB_B;
} }
} }
/* if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS))
* We have no way to tell, so assume extended ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
* translation is enabled.
*/
ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
break; break;
} }
case AHC_VL: case AHC_VL:
{ {
aha2840_load_seeprom(ahc); have_seeprom = aha2840_load_seeprom(ahc);
break; break;
} }
default: default:
break; break;
} }
if (have_seeprom == 0) {
free(ahc->seep_config, M_DEVBUF);
ahc->seep_config = NULL;
}
/* /*
* Ensure autoflush is enabled * Ensure autoflush is enabled
...@@ -209,24 +233,22 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry) ...@@ -209,24 +233,22 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry)
if (error != 0) if (error != 0)
return (error); return (error);
error = aic7770_map_int(ahc, irq);
if (error != 0)
return (error);
ahc_list_lock(&l);
/* /*
* Link this softc in with all other ahc instances. * Link this softc in with all other ahc instances.
*/ */
ahc_softc_insert(ahc); ahc_softc_insert(ahc);
error = aic7770_map_int(ahc, irq);
if (error != 0)
return (error);
/* /*
* Enable the board's BUS drivers * Enable the board's BUS drivers
*/ */
ahc_outb(ahc, BCTL, ENABLE); ahc_outb(ahc, BCTL, ENABLE);
/* ahc_list_unlock(&l);
* Allow interrupts.
*/
ahc_intr_enable(ahc, TRUE);
return (0); return (0);
} }
...@@ -234,14 +256,13 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry) ...@@ -234,14 +256,13 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry)
/* /*
* Read the 284x SEEPROM. * Read the 284x SEEPROM.
*/ */
static void static int
aha2840_load_seeprom(struct ahc_softc *ahc) aha2840_load_seeprom(struct ahc_softc *ahc)
{ {
struct seeprom_descriptor sd; struct seeprom_descriptor sd;
struct seeprom_config sc; struct seeprom_config *sc;
uint16_t checksum = 0; int have_seeprom;
uint8_t scsi_conf; uint8_t scsi_conf;
int have_seeprom;
sd.sd_ahc = ahc; sd.sd_ahc = ahc;
sd.sd_control_offset = SEECTL_2840; sd.sd_control_offset = SEECTL_2840;
...@@ -254,23 +275,16 @@ aha2840_load_seeprom(struct ahc_softc *ahc) ...@@ -254,23 +275,16 @@ aha2840_load_seeprom(struct ahc_softc *ahc)
sd.sd_CK = CK_2840; sd.sd_CK = CK_2840;
sd.sd_DO = DO_2840; sd.sd_DO = DO_2840;
sd.sd_DI = DI_2840; sd.sd_DI = DI_2840;
sc = ahc->seep_config;
if (bootverbose) if (bootverbose)
printf("%s: Reading SEEPROM...", ahc_name(ahc)); printf("%s: Reading SEEPROM...", ahc_name(ahc));
have_seeprom = read_seeprom(&sd, have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
(uint16_t *)&sc, /*start_addr*/0, sizeof(sc)/2);
/*start_addr*/0,
sizeof(sc)/2);
if (have_seeprom) { if (have_seeprom) {
/* Check checksum */
int i; if (ahc_verify_cksum(sc) == 0) {
int maxaddr = (sizeof(sc)/2) - 1;
uint16_t *scarray = (uint16_t *)&sc;
for (i = 0; i < maxaddr; i++)
checksum = checksum + scarray[i];
if (checksum != sc.checksum) {
if(bootverbose) if(bootverbose)
printf ("checksum error\n"); printf ("checksum error\n");
have_seeprom = 0; have_seeprom = 0;
...@@ -288,41 +302,44 @@ aha2840_load_seeprom(struct ahc_softc *ahc) ...@@ -288,41 +302,44 @@ aha2840_load_seeprom(struct ahc_softc *ahc)
* Put the data we've collected down into SRAM * Put the data we've collected down into SRAM
* where ahc_init will find it. * where ahc_init will find it.
*/ */
int i; int i;
int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8; int max_targ;
uint16_t discenable; uint16_t discenable;
max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
discenable = 0; discenable = 0;
for (i = 0; i < max_targ; i++){ for (i = 0; i < max_targ; i++){
uint8_t target_settings; uint8_t target_settings;
target_settings = (sc.device_flags[i] & CFXFER) << 4;
if (sc.device_flags[i] & CFSYNCH) target_settings = (sc->device_flags[i] & CFXFER) << 4;
if (sc->device_flags[i] & CFSYNCH)
target_settings |= SOFS; target_settings |= SOFS;
if (sc.device_flags[i] & CFWIDEB) if (sc->device_flags[i] & CFWIDEB)
target_settings |= WIDEXFER; target_settings |= WIDEXFER;
if (sc.device_flags[i] & CFDISC) if (sc->device_flags[i] & CFDISC)
discenable |= (0x01 << i); discenable |= (0x01 << i);
ahc_outb(ahc, TARG_SCSIRATE + i, target_settings); ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
} }
ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
ahc->our_id = sc.brtime_id & CFSCSIID; ahc->our_id = sc->brtime_id & CFSCSIID;
scsi_conf = (ahc->our_id & 0x7); scsi_conf = (ahc->our_id & 0x7);
if (sc.adapter_control & CFSPARITY) if (sc->adapter_control & CFSPARITY)
scsi_conf |= ENSPCHK; scsi_conf |= ENSPCHK;
if (sc.adapter_control & CFRESETB) if (sc->adapter_control & CFRESETB)
scsi_conf |= RESET_SCSI; scsi_conf |= RESET_SCSI;
if (sc.bios_control & CF284XEXTEND) if (sc->bios_control & CF284XEXTEND)
ahc->flags |= AHC_EXTENDED_TRANS_A; ahc->flags |= AHC_EXTENDED_TRANS_A;
/* Set SCSICONF info */ /* Set SCSICONF info */
ahc_outb(ahc, SCSICONF, scsi_conf); ahc_outb(ahc, SCSICONF, scsi_conf);
if (sc.adapter_control & CF284XSTERM) if (sc->adapter_control & CF284XSTERM)
ahc->flags |= AHC_TERM_ENB_A; ahc->flags |= AHC_TERM_ENB_A;
} }
return (have_seeprom);
} }
static int static int
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_linux.c#9 $ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#11 $
*/ */
#include "aic7xxx_osm.h" #include "aic7xxx_osm.h"
...@@ -55,9 +55,6 @@ aic7770_linux_probe(Scsi_Host_Template *template) ...@@ -55,9 +55,6 @@ aic7770_linux_probe(Scsi_Host_Template *template)
int eisaBase; int eisaBase;
int found; int found;
if (aic7xxx_no_probe)
return (0);
eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET; eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
found = 0; found = 0;
for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) { for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
...@@ -103,10 +100,9 @@ aic7770_linux_probe(Scsi_Host_Template *template) ...@@ -103,10 +100,9 @@ aic7770_linux_probe(Scsi_Host_Template *template)
*/ */
break; break;
} }
ahc->tag = BUS_SPACE_PIO; error = aic7770_config(ahc, entry, eisaBase);
ahc->bsh.ioport = eisaBase;
error = aic7770_config(ahc, entry);
if (error != 0) { if (error != 0) {
ahc->bsh.ioport = 0;
ahc_free(ahc); ahc_free(ahc);
continue; continue;
} }
...@@ -120,18 +116,19 @@ aic7770_linux_probe(Scsi_Host_Template *template) ...@@ -120,18 +116,19 @@ aic7770_linux_probe(Scsi_Host_Template *template)
} }
int int
aic7770_map_registers(struct ahc_softc *ahc) aic7770_map_registers(struct ahc_softc *ahc, u_int port)
{ {
/* /*
* Lock out other contenders for our i/o space. * Lock out other contenders for our i/o space.
*/ */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx"); request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
#else #else
if (request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx") == 0) if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
return (ENOMEM); return (ENOMEM);
#endif #endif
ahc->tag = BUS_SPACE_PIO;
ahc->bsh.ioport = port;
return (0); return (0);
} }
...@@ -145,9 +142,9 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq) ...@@ -145,9 +142,9 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0) if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
shared = SA_SHIRQ; shared = SA_SHIRQ;
ahc->platform_data->irq = irq; error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
error = request_irq(ahc->platform_data->irq, ahc_linux_isr, if (error == 0)
shared, "aic7xxx", ahc); ahc->platform_data->irq = irq;
return (-error); return (-error);
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2000-2001 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* sym driver.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#11 $
*/
#include "aic79xx_osm.h"
#include "aic79xx_inline.h"
static void copy_mem_info(struct info_str *info, char *data, int len);
static int copy_info(struct info_str *info, char *fmt, ...);
static void ahd_dump_target_state(struct ahd_softc *ahd,
struct info_str *info,
u_int our_id, char channel,
u_int target_id, u_int target_offset);
static void ahd_dump_device_state(struct info_str *info,
struct ahd_linux_device *dev);
static int ahd_proc_write_seeprom(struct ahd_softc *ahd,
char *buffer, int length);
static void
copy_mem_info(struct info_str *info, char *data, int len)
{
if (info->pos + len > info->offset + info->length)
len = info->offset + info->length - info->pos;
if (info->pos + len < info->offset) {
info->pos += len;
return;
}
if (info->pos < info->offset) {
off_t partial;
partial = info->offset - info->pos;
data += partial;
info->pos += partial;
len -= partial;
}
if (len > 0) {
memcpy(info->buffer, data, len);
info->pos += len;
info->buffer += len;
}
}
static int
copy_info(struct info_str *info, char *fmt, ...)
{
va_list args;
char buf[256];
int len;
va_start(args, fmt);
len = vsprintf(buf, fmt, args);
va_end(args);
copy_mem_info(info, buf, len);
return (len);
}
void
ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
{
u_int speed;
u_int freq;
u_int mb;
if (tinfo->period == AHD_PERIOD_UNKNOWN) {
copy_info(info, "Renegotiation Pending\n");
return;
}
speed = 3300;
freq = 0;
if (tinfo->offset != 0) {
freq = aic_calc_syncsrate(tinfo->period);
speed = freq;
}
speed *= (0x01 << tinfo->width);
mb = speed / 1000;
if (mb > 0)
copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000);
else
copy_info(info, "%dKB/s transfers", speed);
if (freq != 0) {
int printed_options;
printed_options = 0;
copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000);
if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
copy_info(info, " DT");
printed_options++;
}
if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
copy_info(info, "%s", printed_options ? "|IU" : " IU");
printed_options++;
}
if ((tinfo->ppr_options & MSG_EXT_PPR_RTI) != 0) {
copy_info(info, "%s",
printed_options ? "|RTI" : " RTI");
printed_options++;
}
if ((tinfo->ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
copy_info(info, "%s",
printed_options ? "|QAS" : " QAS");
printed_options++;
}
}
if (tinfo->width > 0) {
if (freq != 0) {
copy_info(info, ", ");
} else {
copy_info(info, " (");
}
copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width));
} else if (freq != 0) {
copy_info(info, ")");
}
copy_info(info, "\n");
}
static void
ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
u_int our_id, char channel, u_int target_id,
u_int target_offset)
{
struct ahd_linux_target *targ;
struct ahd_initiator_tinfo *tinfo;
struct ahd_tmode_tstate *tstate;
int lun;
tinfo = ahd_fetch_transinfo(ahd, channel, our_id,
target_id, &tstate);
copy_info(info, "Channel %c Target %d Negotiation Settings\n",
channel, target_id);
copy_info(info, "\tUser: ");
ahd_format_transinfo(info, &tinfo->user);
targ = ahd->platform_data->targets[target_offset];
if (targ == NULL)
return;
copy_info(info, "\tGoal: ");
ahd_format_transinfo(info, &tinfo->goal);
copy_info(info, "\tCurr: ");
ahd_format_transinfo(info, &tinfo->curr);
copy_info(info, "\tTransmission Errors %ld\n", targ->errors_detected);
for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
struct ahd_linux_device *dev;
dev = targ->devices[lun];
if (dev == NULL)
continue;
ahd_dump_device_state(info, dev);
}
}
static void
ahd_dump_device_state(struct info_str *info, struct ahd_linux_device *dev)
{
copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
dev->target->channel + 'A', dev->target->target, dev->lun);
copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued);
copy_info(info, "\t\tCommands Active %d\n", dev->active);
copy_info(info, "\t\tCommand Openings %d\n", dev->openings);
copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags);
copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
}
static int
ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
{
ahd_mode_state saved_modes;
int have_seeprom;
u_long s;
int paused;
int written;
/* Default to failure. */
written = -EINVAL;
ahd_lock(ahd, &s);
paused = ahd_is_paused(ahd);
if (!paused)
ahd_pause(ahd);
saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
if (length != sizeof(struct seeprom_config)) {
printf("ahd_proc_write_seeprom: incorrect buffer size\n");
goto done;
}
have_seeprom = ahd_verify_cksum((struct seeprom_config*)buffer);
if (have_seeprom == 0) {
printf("ahd_proc_write_seeprom: cksum verification failed\n");
goto done;
}
have_seeprom = ahd_acquire_seeprom(ahd);
if (!have_seeprom) {
printf("ahd_proc_write_seeprom: No Serial EEPROM\n");
goto done;
} else {
u_int start_addr;
if (ahd->seep_config == NULL) {
ahd->seep_config = malloc(sizeof(*ahd->seep_config),
M_DEVBUF, M_NOWAIT);
if (ahd->seep_config == NULL) {
printf("aic79xx: Unable to allocate serial "
"eeprom buffer. Write failing\n");
goto done;
}
}
printf("aic79xx: Writing Serial EEPROM\n");
start_addr = 32 * (ahd->channel - 'A');
ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr,
sizeof(struct seeprom_config)/2);
ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config,
start_addr, sizeof(struct seeprom_config)/2);
ahd_release_seeprom(ahd);
written = length;
}
done:
ahd_restore_modes(ahd, saved_modes);
if (!paused)
ahd_unpause(ahd);
ahd_unlock(ahd, &s);
return (written);
}
/*
* Return information to handle /proc support for the driver.
*/
int
ahd_linux_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
{
struct ahd_softc *ahd;
struct info_str info;
char ahd_info[256];
u_long l;
u_int max_targ;
u_int i;
int retval;
retval = -EINVAL;
ahd_list_lock(&l);
TAILQ_FOREACH(ahd, &ahd_tailq, links) {
if (ahd->platform_data->host->host_no == hostno)
break;
}
if (ahd == NULL)
goto done;
/* Has data been written to the file? */
if (inout == TRUE) {
retval = ahd_proc_write_seeprom(ahd, buffer, length);
goto done;
}
if (start)
*start = buffer;
info.buffer = buffer;
info.length = length;
info.offset = offset;
info.pos = 0;
copy_info(&info, "Adaptec AIC79xx driver version: %s\n",
AIC79XX_DRIVER_VERSION);
ahd_controller_info(ahd, ahd_info);
copy_info(&info, "%s\n\n", ahd_info);
if (ahd->seep_config == NULL)
copy_info(&info, "No Serial EEPROM\n");
else {
copy_info(&info, "Serial EEPROM:\n");
for (i = 0; i < sizeof(*ahd->seep_config)/2; i++) {
if (((i % 8) == 0) && (i != 0)) {
copy_info(&info, "\n");
}
copy_info(&info, "0x%.4x ",
((uint16_t*)ahd->seep_config)[i]);
}
copy_info(&info, "\n");
}
copy_info(&info, "\n");
max_targ = 15;
if ((ahd->features & AHD_WIDE) == 0)
max_targ = 7;
for (i = 0; i <= max_targ; i++) {
ahd_dump_target_state(ahd, &info, ahd->our_id, 'A',
/*target_id*/i, /*target_offset*/i);
}
retval = info.pos > info.offset ? info.pos - info.offset : 0;
done:
ahd_list_unlock(&l);
return (retval);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -38,9 +38,9 @@ ...@@ -38,9 +38,9 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#7 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#12 $
* *
* $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.h,v 1.8 2000/11/10 20:13:41 gibbs Exp $ * $FreeBSD$
*/ */
#ifndef _AIC7XXX_93CX6_H_ #ifndef _AIC7XXX_93CX6_H_
#define _AIC7XXX_93CX6_H_ #define _AIC7XXX_93CX6_H_
...@@ -93,8 +93,10 @@ do { \ ...@@ -93,8 +93,10 @@ do { \
#define SEEPROM_DATA_INB(sd) \ #define SEEPROM_DATA_INB(sd) \
ahc_inb(sd->sd_ahc, sd->sd_dataout_offset) ahc_inb(sd->sd_ahc, sd->sd_dataout_offset)
int read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf, int ahc_read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
u_int start_addr, u_int count); u_int start_addr, u_int count);
int verify_cksum(struct seeprom_config *sc); int ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
u_int start_addr, u_int count);
int ahc_verify_cksum(struct seeprom_config *sc);
#endif /* _AIC7XXX_93CX6_H_ */ #endif /* _AIC7XXX_93CX6_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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