Say Y here if you intend to run this kernel on the NetWinder.
Include support for the Compaq Personal Server
-CONFIG_PERSONAL_SERVER
+CONFIG_ARCH_PERSONAL_SERVER
Say Y here if you intend to run this kernel on the Compaq
Personal Server.
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_map_sg);
EXPORT_SYMBOL(pci_unmap_sg);
+EXPORT_SYMBOL(pci_dma_supported);
EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(dump_fpu);
if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
bool ' Include support for EBSA285' CONFIG_ARCH_EBSA285
- bool ' Include support for CATS' CONFIG_CATS
+ bool ' Include support for CATS' CONFIG_ARCH_CATS
bool ' Include support for NetWinder' CONFIG_ARCH_NETWINDER
- bool ' Include support for Compaq Personal Server' CONFIG_PERSONAL_SERVER
+ bool ' Include support for Compaq Personal Server' CONFIG_ARCH_PERSONAL_SERVER
fi
if [ "$CONFIG_ADDIN_FOOTBRIDGE" = "y" ]; then
#
# These machines have ISA-DMA
#
-if [ "$CONFIG_CATS" = "y" -o \
+if [ "$CONFIG_ARCH_CATS" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_NETWINDER" = "y" ]; then
define_bool CONFIG_ISA_DMA y
if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_NETWINDER" = "y" -o \
- "$CONFIG_PERSONAL_SERVER" = "y" -o \
- "$CONFIG_CATS" = "y" ]; then
+ "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
+ "$CONFIG_ARCH_CATS" = "y" ]; then
string 'Initial kernel command string' CONFIG_CMDLINE
fi
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
* in head-armv.S.
*/
static struct machine_desc machine_desc[] __attribute__ ((__section__ (".arch.info"))) = {
+#ifdef CONFIG_ARCH_EBSA110
{
MACH_TYPE_EBSA110,
"EBSA110", /* RMK */
NO_VIDEO,
1, 0, 1, 1, 1,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_RPC
+ {
MACH_TYPE_RISCPC,
"Acorn-RiscPC", /* RMK */
0x10000100,
NO_VIDEO,
1, 1, 0, 0, 0,
fixup_acorn
- }, {
- 2,
- "unknown",
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_NEXUSPCI
+ {
MACH_TYPE_NEXUSPCI,
"FTV/PCI", /* Philip Blundell */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_EBSA285
+ {
MACH_TYPE_EBSA285,
"EBSA285", /* RMK */
0x00000100,
0x000a0000, 0x000bffff,
0, 0, 0, 0, 0,
fixup_ebsa285
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_NETWINDER
+ {
MACH_TYPE_NETWINDER,
"Rebel-NetWinder", /* RMK */
0x00000100,
0x000a0000, 0x000bffff,
1, 0, 1, 0, 0,
fixup_netwinder
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_CATS
+ {
MACH_TYPE_CATS,
"Chalice-CATS", /* Philip Blundell */
NO_PARAMS,
0x000a0000, 0x000bffff,
0, 0, 0, 0, 1,
fixup_cats
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_TBOX
+ {
MACH_TYPE_TBOX,
"unknown-TBOX", /* Philip Blundell */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_CO285
+ {
MACH_TYPE_CO285,
"co-EBSA285", /* Mark van Doesburg */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
fixup_coebsa285
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_CLPS7110
+ {
MACH_TYPE_CLPS7110,
"CL-PS7110", /* Werner Almesberger */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_ARC
+ {
MACH_TYPE_ARCHIMEDES,
"Acorn-Archimedes",/* RMK/DAG */
0x0207c000,
NO_VIDEO,
0, 0, 0, 0, 0,
fixup_acorn
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_A5K
+ {
MACH_TYPE_A5K,
"Acorn-A5000", /* RMK/PB */
0x0207c000,
NO_VIDEO,
0, 0, 0, 0, 0,
fixup_acorn
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_ETOILE
+ {
MACH_TYPE_ETOILE,
"Etoile", /* Alex de Vries */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_LACIE_NAS
+ {
MACH_TYPE_LACIE_NAS,
"LaCie_NAS", /* Benjamin Herrenschmidt */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_CLPS7500
+ {
MACH_TYPE_CLPS7500,
"CL-PS7500", /* Philip Blundell */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_SHARK
+ {
MACH_TYPE_SHARK,
"Shark", /* Alexander Schulz */
NO_PARAMS,
0x06000000, 0x06000000+0x001fffff,
0, 0, 0, 0, 0,
NULL
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_SA1100
+ {
MACH_TYPE_SA1100,
"SA1100-based", /* Nicolas Pitre */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
fixup_sa1100
- }, {
+ },
+#endif
+#ifdef CONFIG_ARCH_PERSONAL_SERVER
+ {
MACH_TYPE_PERSONAL_SERVER,
"Compaq Personal Server",
NO_PARAMS,
0, 0, 0, 0, 0,
NULL
}
+#endif
};
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
struct list_head *walk = &bus->devices;
+ struct arm_pci_sysdata *sysdata =
+ (struct arm_pci_sysdata *)bus->sysdata;
+ struct arm_bus_sysdata *busdata;
+ if (bus->number < MAX_NR_BUS)
+ busdata = sysdata->bus + bus->number;
+ else
+ BUG();
+
+ /*
+ * Walk the devices on this bus, working out what we can
+ * and can't support.
+ */
+ for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
+ struct pci_dev *dev = pci_dev_b(walk);
+ u16 status;
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
+
+ /*
+ * If this device does not support fast back to back
+ * transfers, the bus as a whole cannot support them.
+ */
+ if (!(status & PCI_STATUS_FAST_BACK))
+ busdata->features &= ~PCI_COMMAND_FAST_BACK;
+
+ /*
+ * Calculate the maximum devsel latency.
+ */
+ if (busdata->maxdevsel < (status & PCI_STATUS_DEVSEL_MASK))
+ busdata->maxdevsel = (status & PCI_STATUS_DEVSEL_MASK);
+
+ /*
+ * If this device is an ISA bridge, set the have_isa_bridge
+ * flag. We will then go looking for things like keyboard,
+ * etc
+ */
+ if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA ||
+ dev->class >> 8 == PCI_CLASS_BRIDGE_EISA)
+ have_isa_bridge = !0;
+ }
+
+ /*
+ * Now walk the devices again, this time setting them up.
+ */
+ walk = &bus->devices;
for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
struct pci_dev *dev = pci_dev_b(walk);
u16 cmd;
/* Put the chip to sleep in case the driver isn't loaded */
pci_write_config_dword(dev, 0x40, 0x80000000);
- /*
- * If this device is an ISA bridge, set the have_isa_bridge
- * flag. We will then go looking for things like keyboard,
- * etc
- */
- if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA ||
- dev->class >> 8 == PCI_CLASS_BRIDGE_EISA)
- have_isa_bridge = !0;
-
/*
* Set latency timer to 32, and a cache line size to 32 bytes.
- * Also, set system error enable, parity error enable, and
- * fast back to back transaction enable. Disable ROM.
+ * Also, set system error enable, parity error enable.
+ * Disable ROM.
*/
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_FAST_BACK | PCI_COMMAND_SERR |
- PCI_COMMAND_PARITY;
+ cmd |= busdata->features;
pci_write_config_word(dev, PCI_COMMAND, cmd);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
};
#endif
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ARCH_CATS
/* cats host-specific stuff */
static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
};
#endif
-#ifdef CONFIG_PERSONAL_SERVER
+#ifdef CONFIG_ARCH_PERSONAL_SERVER
static int irqmap_personal_server[] __initdata = {
IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
break;
}
#endif
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ARCH_CATS
if (machine_is_cats()) {
hw_pci = &cats_pci;
break;
break;
}
#endif
-#ifdef CONFIG_PERSONAL_SERVER
+#ifdef CONFIG_ARCH_PERSONAL_SERVER
if (machine_is_personal_server()) {
hw_pci = &personal_server_pci;
break;
+#define MAX_NR_BUS 2
+
+struct arm_bus_sysdata {
+ /*
+ * bitmask of features we can turn.
+ * See PCI command register for more info.
+ */
+ u16 features;
+ /*
+ * Maximum devsel for this bus.
+ */
+ u16 maxdevsel;
+};
+
+struct arm_pci_sysdata {
+ struct arm_bus_sysdata bus[MAX_NR_BUS];
+};
+
struct hw_pci {
- void (*init)(void);
+ void (*init)(void);
unsigned long io_start;
unsigned long mem_start;
- u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
- int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
+ u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
+ int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
};
void __init dc21285_init(void);
void __init dc21285_init(void)
{
static struct resource csrmem, csrio;
- unsigned int mem_size;
+ struct arm_pci_sysdata sysdata;
unsigned long cntl;
+ unsigned int mem_size, pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+ int i;
mem_size = (unsigned int)high_memory - PAGE_OFFSET;
*CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000;
*CSR_PCICSRIOBASE = csrio.start;
*CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
*CSR_PCIROMBASE = 0;
- *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER | PCI_COMMAND_FAST_BACK |
- PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
+ *CSR_PCICMD = pci_cmd |
(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
#endif
printk(KERN_DEBUG "PCI: DC21285 footbridge, revision %02lX\n",
*CSR_CLASSREV & 0xff);
- pci_scan_bus(0, &dc21285_ops, NULL);
+ for (i = 0; i < MAX_NR_BUS; i++) {
+ sysdata.bus[i].features = PCI_COMMAND_FAST_BACK |
+ PCI_COMMAND_SERR |
+ PCI_COMMAND_PARITY;
+ sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
+ }
+
+ pci_scan_bus(0, &dc21285_ops, &sysdata);
+
+ pci_cmd |= sysdata.bus[0].features;
+
+ printk("Fast back to back PCI transfers %sabled\n",
+ (sysdata.bus[0].features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
/*
* Clear any existing errors - we aren't
* interested in historical data...
*/
- cntl = *CSR_SA110_CNTL & 0xffffde07;
- *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
- cntl = *CSR_PCICMD & 0x0000ffff;
- *CSR_PCICMD = cntl | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
+ cntl = *CSR_SA110_CNTL & 0xffffde07;
+ *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+ *CSR_PCICMD = pci_cmd | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
/*
* Initialise PCI error IRQ after we've finished probing
/*
* CATS stuff
*/
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ARCH_CATS
#define CONFIG_PORT 0x370
#define INDEX_PORT (CONFIG_PORT)
#endif
}
#endif
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ARCH_CATS
if (machine_is_cats())
cats_hw_init();
#endif
/*
* linux/arch/arm/kernel/process.c
*
- * Copyright (C) 1996-1999 Russell King - Converted to ARM.
+ * Copyright (C) 1996-2000 Russell King - Converted to ARM.
* Origional Copyright (C) 1995 Linus Torvalds
*/
#include <asm/io.h>
extern char *processor_modes[];
+extern void setup_mm_for_reboot(char mode);
asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
void machine_restart(char * __unused)
{
/*
- * Turn off caches, interrupts, etc
+ * Clean and disable cache, and turn off interrupts
*/
cpu_proc_fin();
+ /*
+ * Tell the mm system that we are going to reboot -
+ * we may need it to insert some 1:1 mappings so that
+ * soft boot works.
+ */
+ setup_mm_for_reboot(reboot_mode);
+
+ /*
+ * Now call the architecture specific reboot code.
+ */
arch_reset(reboot_mode);
+ /*
+ * Whoops - the architecture was unable to reboot.
+ * Tell the user!
+ */
mdelay(1000);
printk("Reboot failed -- System halted\n");
- cli();
while (1);
}
*/
#define BUG_PROC_MSG \
KERN_DEBUG "Weird data abort (%08X).\n" \
- KERN_DEBUG "Please see http://www.arm.linux.org.uk/state.html for more information"
+ KERN_DEBUG "Please see http://www.arm.linux.org.uk/state.html for " \
+ "more information\n"
asmlinkage void
do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
*
* Page table sludge for older ARM processor architectures.
*
- * Copyright (C) 1998-1999 Russell King
+ * Copyright (C) 1998-2000 Russell King
*/
#include <linux/sched.h>
#include <linux/mm.h>
return (pte_t *) pmd_page(*pmd) + offset;
}
+/*
+ * No special code is required here.
+ */
+void setup_mm_for_reboot(char mode)
+{
+}
+
/*
* This contains the code to setup the memory map on an ARM2/ARM250/ARM3
* machine. This is both processor & architecture specific, and requires
pgd_val(swapper_pg_dir[i]) = 0;
}
+/*
+ * We never have holes in the memmap
+ */
void __init create_memmap_holes(void)
{
}
*
* Page table sludge for ARM v3 and v4 processor architectures.
*
- * Copyright (C) 1998-1999 Russell King
+ * Copyright (C) 1998-2000 Russell King
*/
#include <linux/sched.h>
#include <linux/mm.h>
}
}
+/*
+ * In order to soft-boot, we need to insert a 1:1 mapping in place of
+ * the user-mode pages. This will then ensure that we have predictable
+ * results when turning the mmu off
+ */
+void setup_mm_for_reboot(char mode)
+{
+ pgd_t *pgd = current->mm->pgd;
+ pmd_t pmd;
+ int i;
+
+ for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) {
+ pmd_val(pmd) = (i << PGDIR_SHIFT) |
+ PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
+ PMD_TYPE_SECT;
+ set_pmd(pmd_offset(pgd + i, i << PGDIR_SHIFT), pmd);
+ }
+}
+
void __init pagetable_init(void)
{
struct map_desc *init_maps, *p, *q;
/*
* linux/arch/arm/mm/proc-arm6,7.S: MMU functions for ARM6
*
- * (C) 1997-1999 Russell King
+ * (C) 1997-2000 Russell King
*
* These are the low level assembler for performing cache and TLB
* functions on the ARM6 & ARM7.
/*
* Function: _arm6_7_reset
- *
+ * Params : r0 = address to jump to
* Notes : This sets up everything for a reset
*/
ENTRY(cpu_arm6_reset)
ENTRY(cpu_arm7_reset)
- mov r0, #0
- mcr p15, 0, r0, c7, c0, 0 @ flush cache
- mcr p15, 0, r0, c5, c0, 0 @ flush TLB
- mov pc, lr
+ mov r1, #0
+ mcr p15, 0, r1, c7, c0, 0 @ flush cache
+ mcr p15, 0, r1, c5, c0, 0 @ flush TLB
+ mov r1, #0x30
+ mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc
+ mov pc, r0
cpu_armvlsi_name:
.asciz "ARM/VLSI"
/*
* linux/arch/arm/mm/proc-sa110.S: MMU functions for SA110
*
- * (C) 1997-1999 Russell King
+ * (C) 1997-2000 Russell King
*
* These are the low level assembler for performing cache and TLB
* functions on the StrongARM-110 and StrongARM-1100
.align 5
ENTRY(cpu_sa110_flush_tlb_all)
ENTRY(cpu_sa1100_flush_tlb_all)
- mov r0, #0
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mcr p15, 0, r0, c8, c7, 0 @ flush I & D tlbs
+ mov ip, #0
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs
mov pc, lr
/*
ENTRY(cpu_sa110_proc_fin)
ENTRY(cpu_sa1100_proc_fin)
+ stmfd sp!, {r1, lr}
mrs r0, cpsr
orr r0, r0, #F_BIT | I_BIT
msr cpsr, r0
+ bl cpu_sa110_flush_cache_all @ clean caches
mov r0, #0
mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
mrc p15, 0, r0, c1, c0, 0
- bic r0, r0, #0x1100 @ ...i...s........
+ bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- mov pc, lr
+ ldmfd sp!, {r1, pc}
.align 5
ENTRY(cpu_sa110_do_idle)
/*
* Function: sa110_reset
+ * Params : r0 = address to jump to
* Notes : This sets up everything for a reset
*/
+ .align 5
ENTRY(cpu_sa110_reset)
ENTRY(cpu_sa1100_reset)
- stmfd sp!, {r1, lr}
- bl cpu_sa110_flush_cache_all
- bl cpu_sa110_flush_tlb_all
+ mov ip, #0
mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches
- mrc p15, 0, r0, c1, c0, 0 @ ctrl register
- bic r0, r0, #0x000f @ ............wcam
- bic r0, r0, #0x1100 @ ...i...s........
- ldmfd sp!, {r1, pc}
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
/*
* Purpose : Function pointers used to access above functions - all calls
* come through these
cld
cli
movl $(__KERNEL_DS),%eax
- movl %ax,%ds
- movl %ax,%es
- movl %ax,%fs
- movl %ax,%gs
+ movl %eax,%ds
+ movl %eax,%es
+ movl %eax,%fs
+ movl %eax,%gs
lss SYMBOL_NAME(stack_start),%esp
xorl %eax,%eax
unsigned int n, dummy, *v, ecx, edx;
/* Actually we must have cpuid or we could never have
- * figured out that this was AMD from the vendor info :-).
+ * figured out that this was AMD/Cyrix from the vendor info :-).
*/
cpuid(0x80000000, &n, &dummy, &dummy, &dummy);
cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
c->x86_model_id[48] = 0;
/* Set MTRR capability flag if appropriate */
- if(boot_cpu_data.x86 == 5) {
- if((boot_cpu_data.x86_model == 9) ||
- ((boot_cpu_data.x86_model == 8) &&
- (boot_cpu_data.x86_mask >= 8)))
- c->x86_capability |= X86_FEATURE_MTRR;
- }
-
- if (n >= 0x80000005){
- cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
- printk("CPU: L1 I Cache: %dK L1 D Cache: %dK\n",
- ecx>>24, edx>>24);
- c->x86_cache_size=(ecx>>24)+(edx>>24);
- }
- if (n >= 0x80000006){
- cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
- printk("CPU: L2 Cache: %dK\n", ecx>>16);
- c->x86_cache_size=(ecx>>16);
+
+ if(c->x86_vendor==X86_VENDOR_AMD)
+ {
+ if(boot_cpu_data.x86 == 5) {
+ if((boot_cpu_data.x86_model == 9) ||
+ ((boot_cpu_data.x86_model == 8) &&
+ (boot_cpu_data.x86_mask >= 8)))
+ c->x86_capability |= X86_FEATURE_MTRR;
+ }
+
+ if (n >= 0x80000005){
+ cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
+ printk("CPU: L1 I Cache: %dK L1 D Cache: %dK\n",
+ ecx>>24, edx>>24);
+ c->x86_cache_size=(ecx>>24)+(edx>>24);
+ }
+ if (n >= 0x80000006){
+ cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
+ printk("CPU: L2 Cache: %dK\n", ecx>>16);
+ c->x86_cache_size=(ecx>>16);
+ }
}
return 1;
}
printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n");
isa_dma_bridge_buggy = 2;
#endif
+ c->x86_cache_size=16; /* Yep 16K integrated cache thats it */
+
/* GXm supports extended cpuid levels 'ala' AMD */
if (c->cpuid_level == 2) {
get_model_name(c); /* get CPU marketing name */
tristate ' Sun QuadEthernet support' CONFIG_SUNQE
if [ "$CONFIG_PCI" = "y" ]; then
tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
+ tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_TULIP
tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
tristate 'RealTek RTL-8139 support' CONFIG_8139TOO
tristate 'PCI NE2000 support' CONFIG_NE2K_PCI
CONFIG_SUNBMAC=m
CONFIG_SUNQE=m
CONFIG_DE4X5=m
+CONFIG_TULIP=m
CONFIG_VORTEX=m
CONFIG_8139TOO=m
CONFIG_NE2K_PCI=m
fi
fi
tristate 'XT hard disk support' CONFIG_BLK_DEV_XD
-dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT
+dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARPORT
if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
source drivers/block/paride/Config.in
fi
/* -*- linux-c -*-
- * dtlk.c - DoubleTalk PC driver for Linux kernel 2.0.29
- *
- * $Id: dtlk.c,v 1.19 1999/02/28 12:13:13 jrv Exp jrv $
+ * dtlk.c - DoubleTalk PC driver for Linux
*
* Original author: Chris Pallotta <chris@allmedia.com>
* Current maintainer: Jim Van Zandt <jrv@vanzandt.mv.com>
+ *
+ * 2000-03-18 Jim Van Zandt: Fix polling.
+ * Eliminate dtlk_timer_active flag and separate dtlk_stop_timer
+ * function. Don't restart timer in dtlk_timer_tick. Restart timer
+ * in dtlk_poll after every poll. dtlk_poll returns mask (duh).
+ * Eliminate unused function dtlk_write_byte. Misc. code cleanups.
*/
/* This driver is for the DoubleTalk PC, a speech synthesizer
static int dtlk_port_lpc;
static int dtlk_port_tts;
static int dtlk_busy;
-static int dtlk_timer_active;
static int dtlk_has_indexing;
static unsigned int dtlk_portlist[] =
{0x25e, 0x29e, 0x2de, 0x31e, 0x35e, 0x39e, 0};
static int dtlk_readable(void);
static char dtlk_read_lpc(void);
static char dtlk_read_tts(void);
-static void dtlk_stop_timer(void);
static int dtlk_writeable(void);
static char dtlk_write_bytes(const char *buf, int n);
static char dtlk_write_tts(char);
/*
static void dtlk_handle_error(char, char, unsigned int);
- static char dtlk_write_byte(unsigned int, const char*);
*/
static void dtlk_timer_tick(unsigned long data);
poll_wait(file, &dtlk_process_list, wait);
if (dtlk_has_indexing && dtlk_readable()) {
- dtlk_stop_timer();
+ del_timer(&dtlk_timer);
mask = POLLIN | POLLRDNORM;
}
if (dtlk_writeable()) {
- dtlk_stop_timer();
+ del_timer(&dtlk_timer);
mask |= POLLOUT | POLLWRNORM;
}
/* there are no exception conditions */
- if (mask == 0 && !dtlk_timer_active) {
- /* not ready just yet. There won't be any interrupts,
- so we set a timer instead. */
- dtlk_timer_active = 1;
- dtlk_timer.expires = jiffies + HZ / 100;
- add_timer(&dtlk_timer);
- }
- return 0;
-}
+ /* There won't be any interrupts, so we set a timer instead. */
+ del_timer(&dtlk_timer);
+ dtlk_timer.expires = jiffies + 3*HZ / 100;
+ add_timer(&dtlk_timer);
-static void dtlk_stop_timer()
-{
- if (dtlk_timer_active) {
- dtlk_timer_active = 0;
- del_timer(&dtlk_timer);
- }
+ return mask;
}
static void dtlk_timer_tick(unsigned long data)
{
-
+ TRACE_TEXT(" dtlk_timer_tick");
wake_up_interruptible(&dtlk_process_list);
-
- if (dtlk_timer_active) {
- del_timer(&dtlk_timer);
- dtlk_timer.expires = jiffies + HZ / 100;
- add_timer(&dtlk_timer);
- }
}
static int dtlk_ioctl(struct inode *inode,
}
TRACE_RET;
- dtlk_stop_timer();
+ del_timer(&dtlk_timer);
return 0;
}
dtlk_port_lpc = 0;
dtlk_port_tts = 0;
dtlk_busy = 0;
- dtlk_timer_active = 0;
dtlk_major = devfs_register_chrdev(0, "dtlk", &dtlk_fops);
if (dtlk_major == 0) {
printk(KERN_ERR "DoubleTalk PC - cannot register device\n");
static int dtlk_readable(void)
{
- TRACE_TEXT(" dtlk_readable");
+#ifdef TRACING
+ printk(" dtlk_readable=%u@%u", inb_p(dtlk_port_lpc) != 0x7f, jiffies);
+#endif
return inb_p(dtlk_port_lpc) != 0x7f;
}
static int dtlk_writeable(void)
{
/* TRACE_TEXT(" dtlk_writeable"); */
-#ifdef TRACING
- printk(" dtlk_writeable(%02x)", inb_p(dtlk_port_tts));
+#ifdef TRACINGMORE
+ printk(" dtlk_writeable=%u", (inb_p(dtlk_port_tts) & TTS_WRITABLE)!=0);
#endif
return inb_p(dtlk_port_tts) & TTS_WRITABLE;
}
appears. */
dtlk_delay(100);
dtlk_has_indexing = dtlk_readable();
-
+#ifdef TRACING
+ printk(", indexing %d\n", dtlk_has_indexing);
+#endif
#ifdef INSCOPE
{
/* This macro records ten samples read from the LPC port, for later display */
int b = 0, i, j;
LOOK
- outb_p(0xff, dtlk_port_lpc);
+ outb_p(0xff, dtlk_port_lpc);
buffer[b++] = 0;
LOOK
- dtlk_write_bytes("\0012I\r", 4);
+ dtlk_write_bytes("\0012I\r", 4);
buffer[b++] = 0;
__delay(50 * loops_per_sec / 1000);
outb_p(0xff, dtlk_port_lpc);
buffer[b++] = 0;
LOOK
- printk("\n");
+ printk("\n");
for (j = 0; j < b; j++)
printk(" %02x", buffer[j]);
printk("\n");
__delay(loops_per_sec / 100); /* 10 ms */
LOOK
- outb_p(0x03, dtlk_port_tts);
+ outb_p(0x03, dtlk_port_tts);
buffer[b++] = 0;
LOOK
- LOOK
+ LOOK
- printk("\n");
+ printk("\n");
for (j = 0; j < b; j++)
printk(" %02x", buffer[j]);
printk("\n");
if (total > 2 && buf[total] == 0x7f)
break;
if (total < sizeof(struct dtlk_settings))
- total++;
+ total++;
}
/*
if (i==50) printk("interrogate() read overrun\n");
/* verify DT is ready, read char, wait for ACK */
do {
portval = inb_p(dtlk_port_tts);
- } while ((portval & TTS_READABLE) == 0 && retries++ < DTLK_MAX_RETRIES);
+ } while ((portval & TTS_READABLE) == 0 &&
+ retries++ < DTLK_MAX_RETRIES);
if (retries == DTLK_MAX_RETRIES)
printk(KERN_ERR "dtlk_read_tts() timeout\n");
retries = 0;
do {
portval = inb_p(dtlk_port_tts);
- } while ((portval & TTS_READABLE) != 0 && retries++ < DTLK_MAX_RETRIES);
+ } while ((portval & TTS_READABLE) != 0 &&
+ retries++ < DTLK_MAX_RETRIES);
if (retries == DTLK_MAX_RETRIES)
printk(KERN_ERR "dtlk_read_tts() timeout\n");
return ch;
}
-#ifdef NEVER
-static char dtlk_write_byte(unsigned int minor, const char *buf)
-{
- char ch;
- int err;
- /* TRACE_TEXT("(dtlk_write_byte"); */
- err = get_user(ch, buf);
- /* printk(" dtlk_write_byte(%d, 0x%02x)", minor, (int)ch); */
-
- ch = dtlk_write_tts(ch);
- /*
- TRACE_RET; */
- return ch;
-}
-#endif /* NEVER */
-
/* write n bytes to tts port */
static char dtlk_write_bytes(const char *buf, int n)
{
static char dtlk_write_tts(char ch)
{
int retries = 0;
-#ifdef TRACING
+#ifdef TRACINGMORE
printk(" dtlk_write_tts(");
if (' ' <= ch && ch <= '~')
printk("'%c'", ch);
if ((inb_p(dtlk_port_tts) & TTS_WRITABLE) == 0)
break;
-#ifdef TRACING
+#ifdef TRACINGMORE
printk(")\n");
#endif
return 0;
if (hwif->noprobe)
return;
+#ifdef CONFIG_BLK_DEV_IDE
if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
extern void probe_cmos_for_drives(ide_hwif_t *);
probe_cmos_for_drives (hwif);
}
+#endif
if ((hwif->chipset != ide_4drives || !hwif->mate->present) &&
#if CONFIG_BLK_DEV_PDC4030
outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
if (nr_serviced >= MAX_SERVICE)
{
- printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n",
+ /* 0xFF is valid for a card removal */
+ if(interrupts!=0xFF)
+ printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n",
dev->name, interrupts);
outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
} else {
else
ei_local->lasttx = 10, ei_local->txing = 0;
}
- else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",
- dev->name, ei_local->lasttx);
+// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",
+// dev->name, ei_local->lasttx);
#else /* EI_PINGPONG */
/*
this_frame = ei_local->rx_start_page;
/* Someday we'll omit the previous, iff we never get this message.
- (There is at least one clone claimed to have a problem.) */
- if (ei_debug > 0 && this_frame != ei_local->current_page)
+ (There is at least one clone claimed to have a problem.)
+
+ Keep quiet if it looks like a card removal. One problem here
+ is that some clones crash in roughly the same way.
+ */
+ if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n",
dev->name, this_frame, ei_local->current_page);
int register_netdev(struct net_device *dev)
{
+ int err;
+
rtnl_lock();
/*
if (dev->name && strchr(dev->name, '%'))
{
+ err = -EBUSY;
if(dev_alloc_name(dev, dev->name)<0)
- return -EBUSY;
+ goto out;
}
/*
if (dev->name && (dev->name[0]==0 || dev->name[0]==' '))
{
+ err = -EBUSY;
if(dev_alloc_name(dev, "eth%d")<0)
- return -EBUSY;
+ goto out;
}
- if (register_netdevice(dev)) {
- rtnl_unlock();
- return -EIO;
- }
+ err = -EIO;
+ if (register_netdevice(dev))
+ goto out;
+
+ err = 0;
+
+out:
rtnl_unlock();
- return 0;
+ return err;
}
void unregister_netdev(struct net_device *dev)
lp->tx_ring[i].status = 0;
}
- lp->init_block.tlen_rlen = TX_RING_LEN_BITS | RX_RING_LEN_BITS;
+ lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
for (i = 0; i < 6; i++)
lp->init_block.phys_addr[i] = dev->dev_addr[i];
lp->init_block.rx_ring = (u32)le32_to_cpu(virt_to_bus(lp->rx_ring));
if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
netif_start_queue(dev);
- else
+ else {
lp->tx_full = 1;
+ netif_stop_queue(dev);
+ }
spin_unlock_irqrestore(&lp->lock, flags);
return 0;
}
#include "tulip.h"
#include <asm/io.h>
#include <linux/etherdevice.h>
+#include <linux/pci.h>
int tulip_rx_copybreak;
/* Refill the Rx ring buffers. */
for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
entry = tp->dirty_rx % RX_RING_SIZE;
- if (tp->rx_skbuff[entry] == NULL) {
+ if (tp->rx_buffers[entry].skb == NULL) {
struct sk_buff *skb;
- skb = tp->rx_skbuff[entry] = dev_alloc_skb(PKT_BUF_SZ);
+ dma_addr_t mapping;
+
+ skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ);
if (skb == NULL)
break;
+
+ mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ,
+ PCI_DMA_FROMDEVICE);
+ tp->rx_buffers[entry].mapping = mapping;
+
skb->dev = dev; /* Mark as being used by this device. */
- tp->rx_ring[entry].buffer1 = virt_to_le32desc(skb->tail);
+ tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
refilled++;
}
tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
skb->dev = dev;
skb_reserve(skb, 2); /* 16 byte align the IP header */
+ pci_dma_sync_single(tp->pdev,
+ tp->rx_buffers[entry].mapping,
+ pkt_len, PCI_DMA_FROMDEVICE);
#if ! defined(__alpha__)
- eth_copy_and_sum(skb, tp->rx_skbuff[entry]->tail, pkt_len, 0);
+ eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+ pkt_len, 0);
skb_put(skb, pkt_len);
#else
- memcpy(skb_put(skb, pkt_len), tp->rx_skbuff[entry]->tail,
- pkt_len);
+ memcpy(skb_put(skb, pkt_len),
+ tp->rx_buffers[entry].skb->tail,
+ pkt_len);
#endif
} else { /* Pass up the skb already on the Rx ring. */
- char *temp = skb_put(skb = tp->rx_skbuff[entry], pkt_len);
- tp->rx_skbuff[entry] = NULL;
+ char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
+ pkt_len);
+
#ifndef final_version
- if (le32desc_to_virt(tp->rx_ring[entry].buffer1) != temp)
+ if (tp->rx_buffers[entry].mapping !=
+ le32_to_cpu(tp->rx_ring[entry].buffer1)) {
printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
- "do not match in tulip_rx: %p vs. %p / %p.\n",
- dev->name,
- le32desc_to_virt(tp->rx_ring[entry].buffer1),
- skb->head, temp);
+ "do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
+ dev->name,
+ le32_to_cpu(tp->rx_ring[entry].buffer1),
+ tp->rx_buffers[entry].mapping,
+ skb->head, temp);
+ }
#endif
+
+ pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
+ PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+
+ tp->rx_buffers[entry].skb = NULL;
+ tp->rx_buffers[entry].mapping = 0;
}
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
if (status < 0)
break; /* It still has not been Txed */
/* Check for Rx filter setup frames. */
- if (tp->tx_skbuff[entry] == NULL)
+ if (tp->tx_buffers[entry].skb == NULL) {
+ pci_unmap_single(tp->pdev,
+ tp->tx_buffers[entry].mapping,
+ sizeof(tp->setup_frame),
+ PCI_DMA_TODEVICE);
continue;
+ }
if (status & 0x8000) {
/* There was an major error, log it. */
#ifdef ETHER_STATS
if (status & 0x0001) tp->stats.tx_deferred++;
#endif
- tp->stats.tx_bytes += tp->tx_skbuff[entry]->len;
+ tp->stats.tx_bytes +=
+ tp->tx_buffers[entry].skb->len;
tp->stats.collisions += (status >> 3) & 15;
tp->stats.tx_packets++;
}
+ pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
+ tp->tx_buffers[entry].skb->len,
+ PCI_DMA_TODEVICE);
+
/* Free the original skb. */
- dev_kfree_skb_irq(tp->tx_skbuff[entry]);
- tp->tx_skbuff[entry] = 0;
+ dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
+ tp->tx_buffers[entry].skb = NULL;
+ tp->tx_buffers[entry].mapping = 0;
tx++;
}
/* check if we card is in suspend mode */
entry = tp->dirty_rx % RX_RING_SIZE;
- if (tp->rx_skbuff[entry] == NULL) {
+ if (tp->rx_buffers[entry].skb == NULL) {
if (tulip_debug > 1)
printk(KERN_WARNING "%s: in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n", dev->name, tp->nir, tp->cur_rx, tp->ttimer, rx);
if (tp->ttimer == 0 || (inl(ioaddr + CSR11) & 0xffff) == 0) {
#define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8))
#endif
-
-/* Condensed operations for readability. */
-#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
-#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
-
-
struct medialeaf {
u8 type;
u8 media;
unsigned char *info;
};
+struct ring_info {
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+};
struct tulip_private {
const char *product_name;
dma_addr_t rx_ring_dma;
dma_addr_t tx_ring_dma;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
+ struct ring_info tx_buffers[TX_RING_SIZE];
/* The addresses of receive-in-place skbuffs. */
- struct sk_buff *rx_skbuff[RX_RING_SIZE];
- char *rx_buffs; /* Address of temporary Rx buffers. */
+ struct ring_info rx_buffers[RX_RING_SIZE];
u16 setup_frame[96]; /* Pseudo-Tx frame to init address table. */
int chip_id;
int revision;
};
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
-#if defined(__alpha__) || defined(__arm__)
+#if defined(__alpha__) || defined(__arm__) || defined(__sparc__)
static int rx_copybreak = 1518;
#else
static int rx_copybreak = 100;
#if defined(__alpha__)
static int csr0 = 0x01A00000 | 0xE000;
-#elif defined(__i386__) || defined(__powerpc__) || defined(__sparc__)
+#elif defined(__i386__) || defined(__powerpc__)
static int csr0 = 0x01A00000 | 0x8000;
+#elif defined(__sparc__)
+/* The UltraSparc PCI controllers will disconnect at every 64-byte
+ * crossing anyways so it makes no sense to tell Tulip to burst
+ * any more than that.
+ */
+static int csr0 = 0x01A00000 | 0x9000;
#elif defined(__arm__)
static int csr0 = 0x01A00000 | 0x4800;
#else
/* This is set_rx_mode(), but without starting the transmitter. */
u16 *eaddrs = (u16 *)dev->dev_addr;
u16 *setup_frm = &tp->setup_frame[15*6];
+ dma_addr_t mapping;
/* 21140 bug: you must add the broadcast address. */
memset(tp->setup_frame, 0xff, sizeof(tp->setup_frame));
*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
+
+ mapping = pci_map_single(tp->pdev, tp->setup_frame,
+ sizeof(tp->setup_frame),
+ PCI_DMA_TODEVICE);
+ tp->tx_buffers[0].skb = NULL;
+ tp->tx_buffers[0].mapping = mapping;
+
/* Put the setup frame on the Tx list. */
tp->tx_ring[0].length = cpu_to_le32(0x08000000 | 192);
- tp->tx_ring[0].buffer1 = virt_to_le32desc(tp->setup_frame);
+ tp->tx_ring[0].buffer1 = cpu_to_le32(mapping);
tp->tx_ring[0].status = cpu_to_le32(DescOwned);
tp->cur_tx++;
tp->rx_ring[i].status = 0x00000000;
tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ);
tp->rx_ring[i].buffer2 = cpu_to_le32(tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * (i + 1));
- tp->rx_skbuff[i] = NULL;
+ tp->rx_buffers[i].skb = NULL;
+ tp->rx_buffers[i].mapping = 0;
}
/* Mark the last entry as wrapping the ring. */
tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP);
tp->rx_ring[i-1].buffer2 = cpu_to_le32(tp->rx_ring_dma);
for (i = 0; i < RX_RING_SIZE; i++) {
+ dma_addr_t mapping;
+
/* Note the receive buffer must be longword aligned.
dev_alloc_skb() provides 16 byte alignment. But do *not*
use skb_reserve() to align the IP header! */
struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
- tp->rx_skbuff[i] = skb;
+ tp->rx_buffers[i].skb = skb;
if (skb == NULL)
break;
+ mapping = pci_map_single(tp->pdev, skb->tail,
+ PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+ tp->rx_buffers[i].mapping = mapping;
skb->dev = dev; /* Mark as being used by this device. */
tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */
- tp->rx_ring[i].buffer1 = virt_to_le32desc(skb->tail);
+ tp->rx_ring[i].buffer1 = cpu_to_le32(mapping);
}
tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
/* The Tx buffer descriptor is filled in as needed, but we
do need to clear the ownership bit. */
for (i = 0; i < TX_RING_SIZE; i++) {
- tp->tx_skbuff[i] = 0;
+ tp->tx_buffers[i].skb = NULL;
+ tp->tx_buffers[i].mapping = 0;
tp->tx_ring[i].status = 0x00000000;
tp->tx_ring[i].buffer2 = cpu_to_le32(tp->tx_ring_dma + sizeof(struct tulip_tx_desc) * (i + 1));
}
struct tulip_private *tp = (struct tulip_private *)dev->priv;
int entry;
u32 flag;
+ dma_addr_t mapping;
unsigned long cpuflags;
/* Caution: the write order is important here, set the field
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % TX_RING_SIZE;
- tp->tx_skbuff[entry] = skb;
- tp->tx_ring[entry].buffer1 = virt_to_le32desc(skb->data);
+ tp->tx_buffers[entry].skb = skb;
+ mapping = pci_map_single(tp->pdev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
+ tp->tx_buffers[entry].mapping = mapping;
+ tp->tx_ring[entry].buffer1 = cpu_to_le32(mapping);
if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
flag = 0x60000000; /* No interrupt */
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = tp->rx_skbuff[i];
- tp->rx_skbuff[i] = 0;
+ struct sk_buff *skb = tp->rx_buffers[i].skb;
+ dma_addr_t mapping = tp->rx_buffers[i].mapping;
+
+ tp->rx_buffers[i].skb = NULL;
+ tp->rx_buffers[i].mapping = 0;
+
tp->rx_ring[i].status = 0; /* Not owned by Tulip chip. */
tp->rx_ring[i].length = 0;
tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */
if (skb) {
+ pci_unmap_single(tp->pdev, mapping, PKT_BUF_SZ,
+ PCI_DMA_FROMDEVICE);
dev_kfree_skb (skb);
}
}
for (i = 0; i < TX_RING_SIZE; i++) {
- if (tp->tx_skbuff[i])
- dev_kfree_skb (tp->tx_skbuff[i]);
- tp->tx_skbuff[i] = 0;
+ struct sk_buff *skb = tp->tx_buffers[i].skb;
+
+ if (skb != NULL) {
+ pci_unmap_single(tp->pdev, tp->tx_buffers[i].mapping,
+ skb->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb (skb);
+ }
+ tp->tx_buffers[i].skb = NULL;
+ tp->tx_buffers[i].mapping = 0;
}
MOD_DEC_USE_COUNT;
if (entry != 0) {
/* Avoid a chip errata by prefixing a dummy entry. */
- tp->tx_skbuff[entry] = 0;
+ tp->tx_buffers[entry].skb = NULL;
+ tp->tx_buffers[entry].mapping = 0;
tp->tx_ring[entry].length =
(entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0;
tp->tx_ring[entry].buffer1 = 0;
entry = tp->cur_tx++ % TX_RING_SIZE;
}
- tp->tx_skbuff[entry] = 0;
+ tp->tx_buffers[entry].skb = NULL;
+ tp->tx_buffers[entry].mapping =
+ pci_map_single(tp->pdev, tp->setup_frame,
+ sizeof(tp->setup_frame),
+ PCI_DMA_TODEVICE);
/* Put the setup frame on the Tx list. */
if (entry == TX_RING_SIZE-1)
tx_flags |= DESC_RING_WRAP; /* Wrap ring. */
tp->tx_ring[entry].length = cpu_to_le32(tx_flags);
- tp->tx_ring[entry].buffer1 = virt_to_le32desc(tp->setup_frame);
+ tp->tx_ring[entry].buffer1 =
+ cpu_to_le32(tp->tx_buffers[entry].mapping);
tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
netif_stop_queue(dev);
And the ASIX must have a burst limit or horrible things happen. */
if (chip_idx == DC21143 && chip_rev == 65)
tp->csr0 &= ~0x01000000;
- else if (chip_idx == AX88140)
- tp->csr0 |= 0x2000;
+ else if (chip_idx == AX88140) {
+ if ((tp->csr0 & 0x3f00) == 0)
+ tp->csr0 |= 0x2000;
+ }
/* The lower four bits are the media type. */
if (board_idx >= 0 && board_idx < MAX_UNITS) {
ac18 PCI1260
ac19 PCI1221
ac1a PCI1210
- ac1b PCI1221
+ ac1b PCI1450
ac1c PCI1225
- ac1d PCI1251
+ ac1d PCI1251A
+ ac1e PCI1211
+ ac1f PCI1251B
ac20 TI 2030
+ ac51 PCI1420
fe00 FireWire Host Controller
fe03 12C01A FireWire Host Controller
104d Sony Corporation
#ifdef CONFIG_CARDBUS
+/*
+ * Generic TI open - TI has an extension for the
+ * INTCTL register that sets the PCI CSC interrupt.
+ * Make sure we set it correctly at open and init
+ * time.
+ */
+static int ti_open(pci_socket_t *socket)
+{
+ u8 new, reg = exca_readb(socket, I365_INTCTL);
+
+ new = reg & ~I365_INTR_ENA;
+ if (socket->cb_irq)
+ new |= I365_INTR_ENA;
+ if (new != reg)
+ exca_writeb(socket, I365_INTCTL, new);
+ return 0;
+}
+
+static int ti_init(pci_socket_t *socket)
+{
+ yenta_init(socket);
+ ti_open(socket);
+ return 0;
+}
+
+static struct pci_socket_ops ti_ops = {
+ ti_open,
+ yenta_close,
+ ti_init,
+ yenta_suspend,
+ yenta_get_status,
+ yenta_get_socket,
+ yenta_set_socket,
+ yenta_get_io_map,
+ yenta_set_io_map,
+ yenta_get_mem_map,
+ yenta_set_mem_map,
+ yenta_proc_setup
+};
+
#define ti_sysctl(socket) ((socket)->private[0])
#define ti_cardctl(socket) ((socket)->private[1])
#define ti_devctl(socket) ((socket)->private[2])
ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
if (socket->cb_irq)
ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
+ ti_open(socket);
return 0;
}
config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket));
config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket));
config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket));
-
+ ti_open(socket);
return 0;
}
ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ);
if (socket->cb_irq)
ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
+ ti_open(socket);
return 0;
}
yenta_init(socket);
config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket));
+ ti_open(socket);
return 0;
}
struct pci_socket_ops *op;
} cardbus_override[] = {
{ PD(TI,1130), &ti113x_ops },
+ { PD(TI,1031), &ti_ops },
{ PD(TI,1131), &ti113x_ops },
{ PD(TI,1250), &ti1250_ops },
+ { PD(TI,1220), &ti_ops },
+ { PD(TI,1221), &ti_ops },
+ { PD(TI,1210), &ti_ops },
+ { PD(TI,1450), &ti_ops },
+ { PD(TI,1225), &ti_ops },
+ { PD(TI,1251A), &ti_ops },
+ { PD(TI,1211), &ti_ops },
+ { PD(TI,1251B), &ti_ops },
+ { PD(TI,1420), &ti_ops },
{ PD(RICOH,RL5C465), &ricoh_ops },
{ PD(RICOH,RL5C466), &ricoh_ops },
{"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0
* extra reset */
+ {"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"YAMAHA", "CRW6416S", "1.0c", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
{"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
{"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */
{"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */
{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
{"CREATIVE","DVD-RAM RAM","*", BLIST_GHOST},
{"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST},
+ {"AOpen", "PD-2 DVD-520S", "*", BLIST_GHOST},
{"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */
{"TOSHIBA","CDROM","*", BLIST_ISROM},
{"TOSHIBA","DVD-RAM SD-W1101","*", BLIST_GHOST},
{"TOSHIBA","DVD-RAM SD-W1111","*", BLIST_GHOST},
+ {"MegaRAID", "LD", "*", BLIST_FORCELUN},
/*
* Must be at end of list...
pos = *ppos;
for (; tmp != &usb_driver_list; tmp = tmp->next) {
struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list);
- start += sprintf (start, "%s\n", driver->name);
+ int minor = driver->fops ? driver->minor : -1;
+ if (minor == -1)
+ start += sprintf (start, " %s\n", driver->name);
+ else
+ start += sprintf (start, "%3d-%3d: %s\n", minor, minor + 15, driver->name);
if (start > end) {
start += sprintf(start, "(truncated)\n");
break;
int cyber2000fb_attach(struct cyberpro_info *info)
{
if (current_par.initialised) {
+ info->dev = current_par.dev;
info->regs = CyberRegs;
info->fb = current_par.screen_base;
info->fb_size = current_par.screen_size;
smem_base = dev->resource[0].start;
mmio_base = dev->resource[0].start + 0x00800000;
+ current_par.dev = dev;
current_par.dev_id = dev->device;
+ err = pci_enable_device(dev);
+ if (err) {
+ printk("%s: unable to enable device: %d\n",
+ current_par.dev_name, err);
+ return err;
+ }
+
/*
* Map in the registers
*/
unsigned int palette_size;
signed int currcon;
char dev_name[32];
- unsigned int initialised;
+ struct pci_dev *dev;
unsigned int dev_id;
+ unsigned int initialised:1;
unsigned int bus_64bit:1;
/*
#define CO_REG_DEST_WIDTH 0xbf218
struct cyberpro_info {
+ struct pci_dev *dev;
unsigned char *regs;
char *fb;
char dev_name[32];
bh, offset)) {
/* On error, skip the f_pos to the
next block. */
- filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
- + sb->s_blocksize;
+ filp->f_pos = (filp->f_pos | (sb->s_blocksize - 1))
+ + 1;
brelse (bh);
return stored;
}
int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link)
{
- u32 len;
+ int len;
len = PTR_ERR(link);
if (IS_ERR(link))
goto out;
len = strlen(link);
- if (len > buflen)
+ if (len > (unsigned) buflen)
len = buflen;
- copy_to_user(buffer, link, len);
+ if (copy_to_user(buffer, link, len))
+ len = -EFAULT;
out:
return len;
}
}
}
- printk(" >");
+ printk(" >\n");
if (hd->part[riscix_minor].nr_sects > 2)
hd->part[riscix_minor].nr_sects = 2;
le32_to_cpu(linuxp->nr_sects));
linuxp ++;
}
- printk(" >");
+ printk(" >\n");
/*
* Prevent someone doing a mkswap or mkfs on this partition
*/
bh, offset)) {
/* On error, skip the f_pos to the
next block. */
- filp->f_pos = (filp->f_pos &
+ filp->f_pos = (filp->f_pos |
(sb->s_blocksize - 1)) +
- sb->s_blocksize;
+ 1;
brelse (bh);
return stored;
}
#include <asm/iomd.h>
-#define arch_do_idle() \
+#define arch_do_idle() \
outb(0, IOMD_SUSMODE)
-#define arch_reset(mode) { \
- outb (0, IOMD_ROMCR0); \
- cli(); \
- __asm__ __volatile__("msr spsr, r1;" \
- "mcr p15, 0, %0, c1, c0, 0;" \
- "movs pc, #0" \
- : \
- : "r" (cpu_reset())); \
- }
+#define arch_reset(mode) \
+ do { \
+ outb (0, IOMD_ROMCR0); \
+ cpu_reset(0); \
+ } while (0);
#define arch_power_off() do { } while (0)
#define arch_do_idle() cpu_do_idle()
#define arch_power_off() do { } while (0)
-
-extern __inline__ void arch_reset(char mode)
-{
- if (mode == 's') {
- __asm__ volatile(
- "mcr p15, 0, %0, c1, c0, 0 @ MMU off
- mov pc, #0x80000000 @ jump to flash"
- : : "r" (cpu_reset()) : "cc");
- }
-}
+#define arch_reset(mode) cpu_reset(0x80000000)
#endif
extern __inline__ void arch_reset(char mode)
{
if (mode == 's') {
- __asm__ volatile (
- "mcr p15, 0, %0, c1, c0, 0 @ MMU off
- mov pc, #0x41000000 @ jump to ROM" : :
- "r" (cpu_reset()) : "cc");
+ /*
+ * Jump into the ROM
+ */
+ cpu_reset(0x41000000);
} else {
if (machine_is_netwinder()) {
/* open up the SuperIO chip
outb(0, IOMD_ROMCR0);
- __asm__ __volatile__(
- "mcr p15, 0, %0, c1, c0, 0\n\t"
- "mov pc, #0"
- : : "r" (cpu_reset()));
+ /*
+ * Jump into the ROM
+ */
+ cpu_reset(0);
}
#else
-#define arch_reset(x) { \
- __asm__ volatile ( \
-" mcr p15, 0, %0, c1, c0 @ MMU off\n" \
-" mov pc, #0\n" : : "r" (cpu_reset()) : "cc"); \
- }
+#define arch_reset(x) cpu_reset(0)
#endif
/*
* Special stuff for a reset
*/
- unsigned long (*reset)(void);
+ volatile void (*reset)(unsigned long addr);
/*
* flush an icached page
*/
#define cpu_set_pgd(pgd) processor._set_pgd(pgd)
#define cpu_set_pmd(pmdp, pmd) processor._set_pmd(pmdp, pmd)
#define cpu_set_pte(ptep, pte) processor._set_pte(ptep, pte)
-#define cpu_reset() processor.reset()
+#define cpu_reset(addr) processor.reset(addr)
#define cpu_flush_icache_area(start,end) processor._flush_icache_area(start,end)
#define cpu_cache_wback_area(start,end) processor._cache_wback_area(start,end)
#define cpu_cache_purge_area(start,end) processor._cache_purge_area(start,end)
extern void cpu_set_pgd(unsigned long pgd_phys);
extern void cpu_set_pmd(pmd_t *pmdp, pmd_t pmd);
extern void cpu_set_pte(pte_t *ptep, pte_t pte);
-extern unsigned long cpu_reset(void);
+extern volatile void cpu_reset(unsigned long addr);
extern void cpu_flush_icache_area(unsigned long start, unsigned long size);
extern void cpu_cache_wback_area(unsigned long start, unsigned long end);
extern void cpu_cache_purge_area(unsigned long start, unsigned long end);
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
+#define MADV_NORMAL 0x0 /* default page-in behavior */
+#define MADV_RANDOM 0x1 /* page-in minimum required */
+#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */
+#define MADV_WILLNEED 0x3 /* pre-fault pages */
+#define MADV_DONTNEED 0x4 /* discard these pages */
+
/* compatibility flags */
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FILE 0
# define machine_is_netwinder() (0)
#endif
-#ifdef CONFIG_CATS
+#ifdef CONFIG_ARCH_CATS
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type
# define machine_is_sa1100() (0)
#endif
-#ifdef CONFIG_PERSONAL_SERVER
+#ifdef CONFIG_ARCH_PERSONAL_SERVER
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type