Jody McIntyre 2005-11-22 12:38:34 -05:00
commit 899a1fc084
186 changed files with 2852 additions and 2340 deletions

12
CREDITS
View File

@ -611,8 +611,7 @@ S: USA
N: Randolph Chung N: Randolph Chung
E: tausq@debian.org E: tausq@debian.org
D: Linux/PA-RISC hacker D: Linux/PA-RISC hacker
S: Los Altos, CA 94022 S: Hong Kong
S: USA
N: Juan Jose Ciarlante N: Juan Jose Ciarlante
W: http://juanjox.kernelnotes.org/ W: http://juanjox.kernelnotes.org/
@ -3405,6 +3404,15 @@ S: Chudenicka 8
S: 10200 Prague 10, Hostivar S: 10200 Prague 10, Hostivar
S: Czech Republic S: Czech Republic
N: Thibaut Varene
E: T-Bone@parisc-linux.org
W: http://www.parisc-linux.org/
P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063
D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there
D: AD1889 sound driver
S: Paris, France
N: Heikki Vatiainen N: Heikki Vatiainen
E: hessu@cs.tut.fi E: hessu@cs.tut.fi
D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks

View File

@ -237,8 +237,10 @@ X!Ilib/string.c
<sect1><title>Driver Support</title> <sect1><title>Driver Support</title>
!Enet/core/dev.c !Enet/core/dev.c
!Enet/ethernet/eth.c !Enet/ethernet/eth.c
!Einclude/linux/etherdevice.h !Iinclude/linux/etherdevice.h
!Enet/core/wireless.c <!-- FIXME: Removed for now since no structured comments in source
X!Enet/core/wireless.c
-->
</sect1> </sect1>
<sect1><title>Synchronous PPP</title> <sect1><title>Synchronous PPP</title>
!Edrivers/net/wan/syncppp.c !Edrivers/net/wan/syncppp.c

View File

@ -1,7 +1,7 @@
Kernel Memory Layout on ARM Linux Kernel Memory Layout on ARM Linux
Russell King <rmk@arm.linux.org.uk> Russell King <rmk@arm.linux.org.uk>
May 21, 2004 (2.6.6) November 17, 2005 (2.6.15)
This document describes the virtual memory layout which the Linux This document describes the virtual memory layout which the Linux
kernel uses for ARM processors. It indicates which regions are kernel uses for ARM processors. It indicates which regions are
@ -37,6 +37,8 @@ ff000000 ffbfffff Reserved for future expansion of DMA
mapping region. mapping region.
VMALLOC_END feffffff Free for platform use, recommended. VMALLOC_END feffffff Free for platform use, recommended.
VMALLOC_END must be aligned to a 2MB
boundary.
VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
Memory returned by vmalloc/ioremap will Memory returned by vmalloc/ioremap will

View File

@ -2907,6 +2907,11 @@ M: zaga@fly.cc.fer.hr
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
S: Maintained S: Maintained
WISTRON LAPTOP BUTTON DRIVER
P: Miloslav Trmac
M: mitr@volny.cz
S: Maintained
WL3501 WIRELESS PCMCIA CARD DRIVER WL3501 WIRELESS PCMCIA CARD DRIVER
P: Arnaldo Carvalho de Melo P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br M: acme@conectiva.com.br

View File

@ -1,7 +1,7 @@
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 15 SUBLEVEL = 15
EXTRAVERSION =-rc1 EXTRAVERSION =-rc2
NAME=Affluent Albatross NAME=Affluent Albatross
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@ -120,7 +120,6 @@ EXPORT_SYMBOL(__arch_strncpy_from_user);
EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_1);
EXPORT_SYMBOL(__get_user_2); EXPORT_SYMBOL(__get_user_2);
EXPORT_SYMBOL(__get_user_4); EXPORT_SYMBOL(__get_user_4);
EXPORT_SYMBOL(__get_user_8);
EXPORT_SYMBOL(__put_user_1); EXPORT_SYMBOL(__put_user_1);
EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_2);

View File

@ -48,8 +48,7 @@ work_pending:
mov r0, sp @ 'regs' mov r0, sp @ 'regs'
mov r2, why @ 'syscall' mov r2, why @ 'syscall'
bl do_notify_resume bl do_notify_resume
disable_irq @ disable interrupts b ret_slow_syscall @ Check work again
b no_work_pending
work_resched: work_resched:
bl schedule bl schedule

View File

@ -595,23 +595,22 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
*/ */
ret |= !valid_user_regs(regs); ret |= !valid_user_regs(regs);
/*
* Block the signal if we were unsuccessful.
*/
if (ret != 0) { if (ret != 0) {
spin_lock_irq(&tsk->sighand->siglock); force_sigsegv(sig, tsk);
sigorsets(&tsk->blocked, &tsk->blocked, return;
&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&tsk->blocked, sig);
recalc_sigpending();
spin_unlock_irq(&tsk->sighand->siglock);
} }
if (ret == 0) /*
return; * Block the signal if we were successful.
*/
spin_lock_irq(&tsk->sighand->siglock);
sigorsets(&tsk->blocked, &tsk->blocked,
&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&tsk->blocked, sig);
recalc_sigpending();
spin_unlock_irq(&tsk->sighand->siglock);
force_sigsegv(sig, tsk);
} }
/* /*

View File

@ -172,6 +172,10 @@ SECTIONS
.comment 0 : { *(.comment) } .comment 0 : { *(.comment) }
} }
/* those must never be empty */ /*
* These must never be empty
* If you have to comment these two assert statements out, your
* binutils is too old (for other reasons as well)
*/
ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")

View File

@ -54,15 +54,6 @@ __get_user_4:
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
.global __get_user_8
__get_user_8:
5: ldrt r2, [r0], #4
6: ldrt r3, [r0]
mov r0, #0
mov pc, lr
__get_user_bad_8:
mov r3, #0
__get_user_bad: __get_user_bad:
mov r2, #0 mov r2, #0
mov r0, #-EFAULT mov r0, #-EFAULT
@ -73,6 +64,4 @@ __get_user_bad:
.long 2b, __get_user_bad .long 2b, __get_user_bad
.long 3b, __get_user_bad .long 3b, __get_user_bad
.long 4b, __get_user_bad .long 4b, __get_user_bad
.long 5b, __get_user_bad_8
.long 6b, __get_user_bad_8
.previous .previous

View File

@ -260,7 +260,7 @@ static void __init clps7500_init_irq(void)
static struct map_desc cl7500_io_desc[] __initdata = { static struct map_desc cl7500_io_desc[] __initdata = {
{ /* IO space */ { /* IO space */
.virtual = IO_BASE, .virtual = (unsigned long)IO_BASE,
.pfn = __phys_to_pfn(IO_START), .pfn = __phys_to_pfn(IO_START),
.length = IO_SIZE, .length = IO_SIZE,
.type = MT_DEVICE .type = MT_DEVICE

View File

@ -14,7 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h> #include <linux/platform_device.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>

View File

@ -293,7 +293,8 @@ static void __init get_assabet_scr(void)
GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */ GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */ GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */ GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */
for(i = 100; i--; scr = GPLR); /* Read GPIO 9:2 */ for(i = 100; i--; ) /* Read GPIO 9:2 */
scr = GPLR;
GPDR |= 0x3fc; /* restore correct pin direction */ GPDR |= 0x3fc; /* restore correct pin direction */
scr &= 0x3fc; /* save as system configuration byte. */ scr &= 0x3fc; /* save as system configuration byte. */
SCR_value = scr; SCR_value = scr;

View File

@ -51,4 +51,4 @@ obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
obj-$(CONFIG_CPU_SA110) += proc-sa110.o obj-$(CONFIG_CPU_SA110) += proc-sa110.o
obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
obj-$(CONFIG_CPU_V6) += proc-v6.o blockops.o obj-$(CONFIG_CPU_V6) += proc-v6.o

View File

@ -1,185 +0,0 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <asm/memory.h>
#include <asm/ptrace.h>
#include <asm/cacheflush.h>
#include <asm/traps.h>
extern struct cpu_cache_fns blk_cache_fns;
#define HARVARD_CACHE
/*
* blk_flush_kern_dcache_page(kaddr)
*
* Ensure that the data held in the page kaddr is written back
* to the page in question.
*
* - kaddr - kernel address (guaranteed to be page aligned)
*/
static void __attribute__((naked))
blk_flush_kern_dcache_page(void *kaddr)
{
asm(
"add r1, r0, %0 \n\
sub r1, r1, %1 \n\
1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c5, 0 \n\
mcr p15, 0, r0, c7, c10, 4 \n\
mov pc, lr"
:
: "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
}
/*
* blk_dma_inv_range(start,end)
*
* Invalidate the data cache within the specified region; we will
* be performing a DMA operation in this region and we want to
* purge old data in the cache.
*
* - start - virtual start address of region
* - end - virtual end address of region
*/
static void __attribute__((naked))
blk_dma_inv_range_unified(unsigned long start, unsigned long end)
{
asm(
"tst r0, %0 \n\
mcrne p15, 0, r0, c7, c11, 1 @ clean unified line \n\
tst r1, %0 \n\
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line\n\
.word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
mov pc, lr"
:
: "I" (L1_CACHE_BYTES - 1));
}
static void __attribute__((naked))
blk_dma_inv_range_harvard(unsigned long start, unsigned long end)
{
asm(
"tst r0, %0 \n\
mcrne p15, 0, r0, c7, c10, 1 @ clean D line \n\
tst r1, %0 \n\
mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line \n\
.word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
mov pc, lr"
:
: "I" (L1_CACHE_BYTES - 1));
}
/*
* blk_dma_clean_range(start,end)
* - start - virtual start address of region
* - end - virtual end address of region
*/
static void __attribute__((naked))
blk_dma_clean_range(unsigned long start, unsigned long end)
{
asm(
".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0 @ blocking \n\
mov r0, #0 \n\
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
mov pc, lr");
}
/*
* blk_dma_flush_range(start,end)
* - start - virtual start address of region
* - end - virtual end address of region
*/
static void __attribute__((naked))
blk_dma_flush_range(unsigned long start, unsigned long end)
{
asm(
".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0 @ blocking \n\
mov pc, lr");
}
static int blockops_trap(struct pt_regs *regs, unsigned int instr)
{
regs->ARM_r4 |= regs->ARM_r2;
regs->ARM_pc += 4;
return 0;
}
static char *func[] = {
"Prefetch data range",
"Clean+Invalidate data range",
"Clean data range",
"Invalidate data range",
"Invalidate instr range"
};
static struct undef_hook blockops_hook __initdata = {
.instr_mask = 0x0fffffd0,
.instr_val = 0x0c401f00,
.cpsr_mask = PSR_T_BIT,
.cpsr_val = 0,
.fn = blockops_trap,
};
static int __init blockops_check(void)
{
register unsigned int err asm("r4") = 0;
unsigned int err_pos = 1;
unsigned int cache_type;
int i;
asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_type));
printk("Checking V6 block cache operations:\n");
register_undef_hook(&blockops_hook);
__asm__ ("mov r0, %0\n\t"
"mov r1, %1\n\t"
"mov r2, #1\n\t"
".word 0xec401f2c @ mcrr p15, 0, r1, r0, c12, 2\n\t"
"mov r2, #2\n\t"
".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0\n\t"
"mov r2, #4\n\t"
".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0\n\t"
"mov r2, #8\n\t"
".word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0\n\t"
"mov r2, #16\n\t"
".word 0xec401f05 @ mcrr p15, 0, r1, r0, c5, 0\n\t"
:
: "r" (PAGE_OFFSET), "r" (PAGE_OFFSET + 128)
: "r0", "r1", "r2");
unregister_undef_hook(&blockops_hook);
for (i = 0; i < ARRAY_SIZE(func); i++, err_pos <<= 1)
printk("%30s: %ssupported\n", func[i], err & err_pos ? "not " : "");
if ((err & 8) == 0) {
printk(" --> Using %s block cache invalidate\n",
cache_type & (1 << 24) ? "harvard" : "unified");
if (cache_type & (1 << 24))
cpu_cache.dma_inv_range = blk_dma_inv_range_harvard;
else
cpu_cache.dma_inv_range = blk_dma_inv_range_unified;
}
if ((err & 4) == 0) {
printk(" --> Using block cache clean\n");
cpu_cache.dma_clean_range = blk_dma_clean_range;
}
if ((err & 2) == 0) {
printk(" --> Using block cache clean+invalidate\n");
cpu_cache.dma_flush_range = blk_dma_flush_range;
cpu_cache.flush_kern_dcache_page = blk_flush_kern_dcache_page;
}
return 0;
}
__initcall(blockops_check);

View File

@ -420,7 +420,8 @@ static void __init bootmem_init(struct meminfo *mi)
* Set up device the mappings. Since we clear out the page tables for all * Set up device the mappings. Since we clear out the page tables for all
* mappings above VMALLOC_END, we will remove any debug device mappings. * mappings above VMALLOC_END, we will remove any debug device mappings.
* This means you have to be careful how you debug this function, or any * This means you have to be careful how you debug this function, or any
* called function. (Do it by code inspection!) * called function. This means you can't use any function or debugging
* method which may touch any device, otherwise the kernel _will_ crash.
*/ */
static void __init devicemaps_init(struct machine_desc *mdesc) static void __init devicemaps_init(struct machine_desc *mdesc)
{ {
@ -428,6 +429,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
unsigned long addr; unsigned long addr;
void *vectors; void *vectors;
/*
* Allocate the vector page early.
*/
vectors = alloc_bootmem_low_pages(PAGE_SIZE);
BUG_ON(!vectors);
for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr)); pmd_clear(pmd_off_k(addr));
@ -461,12 +468,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
create_mapping(&map); create_mapping(&map);
#endif #endif
flush_cache_all();
local_flush_tlb_all();
vectors = alloc_bootmem_low_pages(PAGE_SIZE);
BUG_ON(!vectors);
/* /*
* Create a mapping for the machine vectors at the high-vectors * Create a mapping for the machine vectors at the high-vectors
* location (0xffff0000). If we aren't using high-vectors, also * location (0xffff0000). If we aren't using high-vectors, also
@ -491,12 +492,13 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
mdesc->map_io(); mdesc->map_io();
/* /*
* Finally flush the tlb again - this ensures that we're in a * Finally flush the caches and tlb to ensure that we're in a
* consistent state wrt the writebuffer if the writebuffer needs * consistent state wrt the writebuffer. This also ensures that
* draining. After this point, we can start to touch devices * any write-allocated cache lines in the vector page are written
* again. * back. After this point, we can start to touch devices again.
*/ */
local_flush_tlb_all(); local_flush_tlb_all();
flush_cache_all();
} }
/* /*

View File

@ -130,8 +130,7 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information. * mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/ */
void __iomem * void __iomem *
__ioremap(unsigned long phys_addr, size_t size, unsigned long flags, __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
unsigned long align)
{ {
void * addr; void * addr;
struct vm_struct * area; struct vm_struct * area;

View File

@ -248,9 +248,7 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
acpi_table_print_madt_entry(header); acpi_table_print_madt_entry(header);
/* no utility in registering a disabled processor */ /* Register even disabled CPUs for cpu hotplug */
if (processor->flags.enabled == 0)
return 0;
x86_acpiid_to_apicid[processor->acpi_id] = processor->id; x86_acpiid_to_apicid[processor->acpi_id] = processor->id;

View File

@ -220,8 +220,9 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
num_processors++; num_processors++;
if ((num_processors > 8) && if ((num_processors > 8) &&
APIC_XAPIC(ver) && ((APIC_XAPIC(ver) &&
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ||
(boot_cpu_data.x86_vendor == X86_VENDOR_AMD)))
def_to_bigsmp = 1; def_to_bigsmp = 1;
else else
def_to_bigsmp = 0; def_to_bigsmp = 0;

View File

@ -137,6 +137,7 @@ retry_bteop:
bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index); bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
if (bte == NULL) { if (bte == NULL) {
nasid_index++;
continue; continue;
} }

View File

@ -492,6 +492,9 @@ static struct proc_dir_entry *proc_sn2_ptc;
static int __init sn2_ptc_init(void) static int __init sn2_ptc_init(void)
{ {
if (!ia64_platform_is("sn2"))
return -ENOSYS;
if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) { if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME); printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
return -EINVAL; return -EINVAL;

View File

@ -743,13 +743,14 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) { if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
memset(p, 0, a.sz); memset(p, 0, a.sz);
for (i = 0; i < nobj; i++) { for (i = 0; i < nobj; i++) {
int cpuobj_index = 0;
if (!SN_HWPERF_IS_NODE(objs + i)) if (!SN_HWPERF_IS_NODE(objs + i))
continue; continue;
node = sn_hwperf_obj_to_cnode(objs + i); node = sn_hwperf_obj_to_cnode(objs + i);
for_each_online_cpu(j) { for_each_online_cpu(j) {
if (node != cpu_to_node(j)) if (node != cpu_to_node(j))
continue; continue;
cpuobj = (struct sn_hwperf_object_info *) p + j; cpuobj = (struct sn_hwperf_object_info *) p + cpuobj_index++;
slice = 'a' + cpuid_to_slice(j); slice = 'a' + cpuid_to_slice(j);
cdata = cpu_data(j); cdata = cpu_data(j);
cpuobj->id = j; cpuobj->id = j;

View File

@ -499,8 +499,12 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
dev = create_parisc_device(mod_path); dev = create_parisc_device(mod_path);
if (dev->id.hw_type != HPHW_FAULTY) { if (dev->id.hw_type != HPHW_FAULTY) {
printk("Two devices have hardware path %s. Please file a bug with HP.\n" printk(KERN_ERR "Two devices have hardware path [%s]. "
"In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev)); "IODC data for second device: "
"%02x%02x%02x%02x%02x%02x\n"
"Rearranging GSC cards sometimes helps\n",
parisc_pathname(dev), iodc_data[0], iodc_data[1],
iodc_data[3], iodc_data[4], iodc_data[5], iodc_data[6]);
return NULL; return NULL;
} }

View File

@ -1846,6 +1846,7 @@ sys_clone_wrapper:
ldo -16(%r30),%r29 /* Reference param save area */ ldo -16(%r30),%r29 /* Reference param save area */
#endif #endif
/* WARNING - Clobbers r19 and r21, userspace must save these! */
STREG %r2,PT_GR19(%r1) /* save for child */ STREG %r2,PT_GR19(%r1) /* save for child */
STREG %r30,PT_GR21(%r1) STREG %r30,PT_GR21(%r1)
BL sys_clone,%r2 BL sys_clone,%r2

View File

@ -188,7 +188,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
temp = pa_pdc_cell.cba; temp = pa_pdc_cell.cba;
dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path); dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
if (!dev) { if (!dev) {
return PDC_NE_MOD; return PDC_OK;
} }
/* alloc_pa_dev sets dev->hpa */ /* alloc_pa_dev sets dev->hpa */

View File

@ -19,536 +19,6 @@
#define CODE #define CODE
#include "compat_ioctl.c" #include "compat_ioctl.c"
/* Use this to get at 32-bit user passed pointers.
See sys_sparc32.c for description about these. */
#define A(__x) ((unsigned long)(__x))
/* The same for use with copy_from_user() and copy_to_user(). */
#define B(__x) ((void *)(unsigned long)(__x))
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
/* This really belongs in include/linux/drm.h -DaveM */
#include "../../../drivers/char/drm/drm.h"
typedef struct drm32_version {
int version_major; /* Major version */
int version_minor; /* Minor version */
int version_patchlevel;/* Patch level */
int name_len; /* Length of name buffer */
u32 name; /* Name of driver */
int date_len; /* Length of date buffer */
u32 date; /* User-space buffer to hold date */
int desc_len; /* Length of desc buffer */
u32 desc; /* User-space buffer to hold desc */
} drm32_version_t;
#define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_version_t *uversion = (drm32_version_t *)arg;
char *name_ptr, *date_ptr, *desc_ptr;
u32 tmp1, tmp2, tmp3;
drm_version_t kversion;
mm_segment_t old_fs;
int ret;
memset(&kversion, 0, sizeof(kversion));
if (get_user(kversion.name_len, &uversion->name_len) ||
get_user(kversion.date_len, &uversion->date_len) ||
get_user(kversion.desc_len, &uversion->desc_len) ||
get_user(tmp1, &uversion->name) ||
get_user(tmp2, &uversion->date) ||
get_user(tmp3, &uversion->desc))
return -EFAULT;
name_ptr = (char *) A(tmp1);
date_ptr = (char *) A(tmp2);
desc_ptr = (char *) A(tmp3);
ret = -ENOMEM;
if (kversion.name_len && name_ptr) {
kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
if (!kversion.name)
goto out;
}
if (kversion.date_len && date_ptr) {
kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
if (!kversion.date)
goto out;
}
if (kversion.desc_len && desc_ptr) {
kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
if (!kversion.desc)
goto out;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
set_fs(old_fs);
if (!ret) {
if ((kversion.name &&
copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
(kversion.date &&
copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
(kversion.desc &&
copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
ret = -EFAULT;
if (put_user(kversion.version_major, &uversion->version_major) ||
put_user(kversion.version_minor, &uversion->version_minor) ||
put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
put_user(kversion.name_len, &uversion->name_len) ||
put_user(kversion.date_len, &uversion->date_len) ||
put_user(kversion.desc_len, &uversion->desc_len))
ret = -EFAULT;
}
out:
kfree(kversion.name);
kfree(kversion.date);
kfree(kversion.desc);
return ret;
}
typedef struct drm32_unique {
int unique_len; /* Length of unique */
u32 unique; /* Unique name for driver instantiation */
} drm32_unique_t;
#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_unique_t *uarg = (drm32_unique_t *)arg;
drm_unique_t karg;
mm_segment_t old_fs;
char *uptr;
u32 tmp;
int ret;
if (get_user(karg.unique_len, &uarg->unique_len))
return -EFAULT;
karg.unique = NULL;
if (get_user(tmp, &uarg->unique))
return -EFAULT;
uptr = (char *) A(tmp);
if (uptr) {
karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
if (!karg.unique)
return -ENOMEM;
if (cmd == DRM32_IOCTL_SET_UNIQUE &&
copy_from_user(karg.unique, uptr, karg.unique_len)) {
kfree(karg.unique);
return -EFAULT;
}
}
old_fs = get_fs();
set_fs(KERNEL_DS);
if (cmd == DRM32_IOCTL_GET_UNIQUE)
ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
else
ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
set_fs(old_fs);
if (!ret) {
if (cmd == DRM32_IOCTL_GET_UNIQUE &&
uptr != NULL &&
copy_to_user(uptr, karg.unique, karg.unique_len))
ret = -EFAULT;
if (put_user(karg.unique_len, &uarg->unique_len))
ret = -EFAULT;
}
kfree(karg.unique);
return ret;
}
typedef struct drm32_map {
u32 offset; /* Requested physical address (0 for SAREA)*/
u32 size; /* Requested physical size (bytes) */
drm_map_type_t type; /* Type of memory to map */
drm_map_flags_t flags; /* Flags */
u32 handle; /* User-space: "Handle" to pass to mmap */
/* Kernel-space: kernel-virtual address */
int mtrr; /* MTRR slot used */
/* Private data */
} drm32_map_t;
#define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_map_t *uarg = (drm32_map_t *) arg;
drm_map_t karg;
mm_segment_t old_fs;
u32 tmp;
int ret;
ret = get_user(karg.offset, &uarg->offset);
ret |= get_user(karg.size, &uarg->size);
ret |= get_user(karg.type, &uarg->type);
ret |= get_user(karg.flags, &uarg->flags);
ret |= get_user(tmp, &uarg->handle);
ret |= get_user(karg.mtrr, &uarg->mtrr);
if (ret)
return -EFAULT;
karg.handle = (void *) A(tmp);
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
set_fs(old_fs);
if (!ret) {
ret = put_user(karg.offset, &uarg->offset);
ret |= put_user(karg.size, &uarg->size);
ret |= put_user(karg.type, &uarg->type);
ret |= put_user(karg.flags, &uarg->flags);
tmp = (u32) (long)karg.handle;
ret |= put_user(tmp, &uarg->handle);
ret |= put_user(karg.mtrr, &uarg->mtrr);
if (ret)
ret = -EFAULT;
}
return ret;
}
typedef struct drm32_buf_info {
int count; /* Entries in list */
u32 list; /* (drm_buf_desc_t *) */
} drm32_buf_info_t;
#define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
drm_buf_desc_t *ulist;
drm_buf_info_t karg;
mm_segment_t old_fs;
int orig_count, ret;
u32 tmp;
if (get_user(karg.count, &uarg->count) ||
get_user(tmp, &uarg->list))
return -EFAULT;
ulist = (drm_buf_desc_t *) A(tmp);
orig_count = karg.count;
karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
if (!karg.list)
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
set_fs(old_fs);
if (!ret) {
if (karg.count <= orig_count &&
(copy_to_user(ulist, karg.list,
karg.count * sizeof(drm_buf_desc_t))))
ret = -EFAULT;
if (put_user(karg.count, &uarg->count))
ret = -EFAULT;
}
kfree(karg.list);
return ret;
}
typedef struct drm32_buf_free {
int count;
u32 list; /* (int *) */
} drm32_buf_free_t;
#define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
drm_buf_free_t karg;
mm_segment_t old_fs;
int *ulist;
int ret;
u32 tmp;
if (get_user(karg.count, &uarg->count) ||
get_user(tmp, &uarg->list))
return -EFAULT;
ulist = (int *) A(tmp);
karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
if (!karg.list)
return -ENOMEM;
ret = -EFAULT;
if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
goto out;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
set_fs(old_fs);
out:
kfree(karg.list);
return ret;
}
typedef struct drm32_buf_pub {
int idx; /* Index into master buflist */
int total; /* Buffer size */
int used; /* Amount of buffer in use (for DMA) */
u32 address; /* Address of buffer (void *) */
} drm32_buf_pub_t;
typedef struct drm32_buf_map {
int count; /* Length of buflist */
u32 virtual; /* Mmaped area in user-virtual (void *) */
u32 list; /* Buffer information (drm_buf_pub_t *) */
} drm32_buf_map_t;
#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
drm32_buf_pub_t *ulist;
drm_buf_map_t karg;
mm_segment_t old_fs;
int orig_count, ret, i;
u32 tmp1, tmp2;
if (get_user(karg.count, &uarg->count) ||
get_user(tmp1, &uarg->virtual) ||
get_user(tmp2, &uarg->list))
return -EFAULT;
karg.virtual = (void *) A(tmp1);
ulist = (drm32_buf_pub_t *) A(tmp2);
orig_count = karg.count;
karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
if (!karg.list)
return -ENOMEM;
ret = -EFAULT;
for (i = 0; i < karg.count; i++) {
if (get_user(karg.list[i].idx, &ulist[i].idx) ||
get_user(karg.list[i].total, &ulist[i].total) ||
get_user(karg.list[i].used, &ulist[i].used) ||
get_user(tmp1, &ulist[i].address))
goto out;
karg.list[i].address = (void *) A(tmp1);
}
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
set_fs(old_fs);
if (!ret) {
for (i = 0; i < orig_count; i++) {
tmp1 = (u32) (long) karg.list[i].address;
if (put_user(karg.list[i].idx, &ulist[i].idx) ||
put_user(karg.list[i].total, &ulist[i].total) ||
put_user(karg.list[i].used, &ulist[i].used) ||
put_user(tmp1, &ulist[i].address)) {
ret = -EFAULT;
goto out;
}
}
if (put_user(karg.count, &uarg->count))
ret = -EFAULT;
}
out:
kfree(karg.list);
return ret;
}
typedef struct drm32_dma {
/* Indices here refer to the offset into
buflist in drm_buf_get_t. */
int context; /* Context handle */
int send_count; /* Number of buffers to send */
u32 send_indices; /* List of handles to buffers (int *) */
u32 send_sizes; /* Lengths of data to send (int *) */
drm_dma_flags_t flags; /* Flags */
int request_count; /* Number of buffers requested */
int request_size; /* Desired size for buffers */
u32 request_indices; /* Buffer information (int *) */
u32 request_sizes; /* (int *) */
int granted_count; /* Number of buffers granted */
} drm32_dma_t;
#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
/* RED PEN The DRM layer blindly dereferences the send/request
* indice/size arrays even though they are userland
* pointers. -DaveM
*/
static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_dma_t *uarg = (drm32_dma_t *) arg;
int *u_si, *u_ss, *u_ri, *u_rs;
drm_dma_t karg;
mm_segment_t old_fs;
int ret;
u32 tmp1, tmp2, tmp3, tmp4;
karg.send_indices = karg.send_sizes = NULL;
karg.request_indices = karg.request_sizes = NULL;
if (get_user(karg.context, &uarg->context) ||
get_user(karg.send_count, &uarg->send_count) ||
get_user(tmp1, &uarg->send_indices) ||
get_user(tmp2, &uarg->send_sizes) ||
get_user(karg.flags, &uarg->flags) ||
get_user(karg.request_count, &uarg->request_count) ||
get_user(karg.request_size, &uarg->request_size) ||
get_user(tmp3, &uarg->request_indices) ||
get_user(tmp4, &uarg->request_sizes) ||
get_user(karg.granted_count, &uarg->granted_count))
return -EFAULT;
u_si = (int *) A(tmp1);
u_ss = (int *) A(tmp2);
u_ri = (int *) A(tmp3);
u_rs = (int *) A(tmp4);
if (karg.send_count) {
karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
ret = -ENOMEM;
if (!karg.send_indices || !karg.send_sizes)
goto out;
ret = -EFAULT;
if (copy_from_user(karg.send_indices, u_si,
(karg.send_count * sizeof(int))) ||
copy_from_user(karg.send_sizes, u_ss,
(karg.send_count * sizeof(int))))
goto out;
}
if (karg.request_count) {
karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
ret = -ENOMEM;
if (!karg.request_indices || !karg.request_sizes)
goto out;
ret = -EFAULT;
if (copy_from_user(karg.request_indices, u_ri,
(karg.request_count * sizeof(int))) ||
copy_from_user(karg.request_sizes, u_rs,
(karg.request_count * sizeof(int))))
goto out;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
set_fs(old_fs);
if (!ret) {
if (put_user(karg.context, &uarg->context) ||
put_user(karg.send_count, &uarg->send_count) ||
put_user(karg.flags, &uarg->flags) ||
put_user(karg.request_count, &uarg->request_count) ||
put_user(karg.request_size, &uarg->request_size) ||
put_user(karg.granted_count, &uarg->granted_count))
ret = -EFAULT;
if (karg.send_count) {
if (copy_to_user(u_si, karg.send_indices,
(karg.send_count * sizeof(int))) ||
copy_to_user(u_ss, karg.send_sizes,
(karg.send_count * sizeof(int))))
ret = -EFAULT;
}
if (karg.request_count) {
if (copy_to_user(u_ri, karg.request_indices,
(karg.request_count * sizeof(int))) ||
copy_to_user(u_rs, karg.request_sizes,
(karg.request_count * sizeof(int))))
ret = -EFAULT;
}
}
out:
kfree(karg.send_indices);
kfree(karg.send_sizes);
kfree(karg.request_indices);
kfree(karg.request_sizes);
return ret;
}
typedef struct drm32_ctx_res {
int count;
u32 contexts; /* (drm_ctx_t *) */
} drm32_ctx_res_t;
#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
{
drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
drm_ctx_t *ulist;
drm_ctx_res_t karg;
mm_segment_t old_fs;
int orig_count, ret;
u32 tmp;
karg.contexts = NULL;
if (get_user(karg.count, &uarg->count) ||
get_user(tmp, &uarg->contexts))
return -EFAULT;
ulist = (drm_ctx_t *) A(tmp);
orig_count = karg.count;
if (karg.count && ulist) {
karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
if (!karg.contexts)
return -ENOMEM;
if (copy_from_user(karg.contexts, ulist,
(karg.count * sizeof(drm_ctx_t)))) {
kfree(karg.contexts);
return -EFAULT;
}
}
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
set_fs(old_fs);
if (!ret) {
if (orig_count) {
if (copy_to_user(ulist, karg.contexts,
(orig_count * sizeof(drm_ctx_t))))
ret = -EFAULT;
}
if (put_user(karg.count, &uarg->count))
ret = -EFAULT;
}
kfree(karg.contexts);
return ret;
}
#endif
#define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL }, #define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl)
@ -561,11 +31,6 @@ IOCTL_TABLE_START
#define DECLARES #define DECLARES
#include "compat_ioctl.c" #include "compat_ioctl.c"
/* PA-specific ioctls */
COMPATIBLE_IOCTL(PA_PERF_ON)
COMPATIBLE_IOCTL(PA_PERF_OFF)
COMPATIBLE_IOCTL(PA_PERF_VERSION)
/* And these ioctls need translation */ /* And these ioctls need translation */
HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc) HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc) HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
@ -590,17 +55,6 @@ HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
COMPATIBLE_IOCTL(RTC_EPOCH_SET) COMPATIBLE_IOCTL(RTC_EPOCH_SET)
#endif #endif
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
#endif /* DRM */
IOCTL_TABLE_END IOCTL_TABLE_END
int ioctl_table_size = ARRAY_SIZE(ioctl_start); int ioctl_table_size = ARRAY_SIZE(ioctl_start);

View File

@ -30,6 +30,9 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/io.h>
#include <asm/smp.h>
#undef PARISC_IRQ_CR16_COUNTS #undef PARISC_IRQ_CR16_COUNTS
@ -43,26 +46,34 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
*/ */
static volatile unsigned long cpu_eiem = 0; static volatile unsigned long cpu_eiem = 0;
static void cpu_set_eiem(void *info) static void cpu_disable_irq(unsigned int irq)
{
set_eiem((unsigned long) info);
}
static inline void cpu_disable_irq(unsigned int irq)
{ {
unsigned long eirr_bit = EIEM_MASK(irq); unsigned long eirr_bit = EIEM_MASK(irq);
cpu_eiem &= ~eirr_bit; cpu_eiem &= ~eirr_bit;
on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1); /* Do nothing on the other CPUs. If they get this interrupt,
* The & cpu_eiem in the do_cpu_irq_mask() ensures they won't
* handle it, and the set_eiem() at the bottom will ensure it
* then gets disabled */
} }
static void cpu_enable_irq(unsigned int irq) static void cpu_enable_irq(unsigned int irq)
{ {
unsigned long eirr_bit = EIEM_MASK(irq); unsigned long eirr_bit = EIEM_MASK(irq);
mtctl(eirr_bit, 23); /* clear EIRR bit before unmasking */
cpu_eiem |= eirr_bit; cpu_eiem |= eirr_bit;
on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
/* FIXME: while our interrupts aren't nested, we cannot reset
* the eiem mask if we're already in an interrupt. Once we
* implement nested interrupts, this can go away
*/
if (!in_interrupt())
set_eiem(cpu_eiem);
/* This is just a simple NOP IPI. But what it does is cause
* all the other CPUs to do a set_eiem(cpu_eiem) at the end
* of the interrupt handler */
smp_send_all_nop();
} }
static unsigned int cpu_startup_irq(unsigned int irq) static unsigned int cpu_startup_irq(unsigned int irq)
@ -74,6 +85,35 @@ static unsigned int cpu_startup_irq(unsigned int irq)
void no_ack_irq(unsigned int irq) { } void no_ack_irq(unsigned int irq) { }
void no_end_irq(unsigned int irq) { } void no_end_irq(unsigned int irq) { }
#ifdef CONFIG_SMP
int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
{
int cpu_dest;
/* timer and ipi have to always be received on all CPUs */
if (irq == TIMER_IRQ || irq == IPI_IRQ) {
/* Bad linux design decision. The mask has already
* been set; we must reset it */
irq_affinity[irq] = CPU_MASK_ALL;
return -EINVAL;
}
/* whatever mask they set, we just allow one CPU */
cpu_dest = first_cpu(*dest);
*dest = cpumask_of_cpu(cpu_dest);
return 0;
}
static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest)
{
if (cpu_check_affinity(irq, &dest))
return;
irq_affinity[irq] = dest;
}
#endif
static struct hw_interrupt_type cpu_interrupt_type = { static struct hw_interrupt_type cpu_interrupt_type = {
.typename = "CPU", .typename = "CPU",
.startup = cpu_startup_irq, .startup = cpu_startup_irq,
@ -82,7 +122,9 @@ static struct hw_interrupt_type cpu_interrupt_type = {
.disable = cpu_disable_irq, .disable = cpu_disable_irq,
.ack = no_ack_irq, .ack = no_ack_irq,
.end = no_end_irq, .end = no_end_irq,
// .set_affinity = cpu_set_affinity_irq, #ifdef CONFIG_SMP
.set_affinity = cpu_set_affinity_irq,
#endif
}; };
int show_interrupts(struct seq_file *p, void *v) int show_interrupts(struct seq_file *p, void *v)
@ -219,6 +261,17 @@ int txn_alloc_irq(unsigned int bits_wide)
return -1; return -1;
} }
unsigned long txn_affinity_addr(unsigned int irq, int cpu)
{
#ifdef CONFIG_SMP
irq_affinity[irq] = cpumask_of_cpu(cpu);
#endif
return cpu_data[cpu].txn_addr;
}
unsigned long txn_alloc_addr(unsigned int virt_irq) unsigned long txn_alloc_addr(unsigned int virt_irq)
{ {
static int next_cpu = -1; static int next_cpu = -1;
@ -233,7 +286,7 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
if (next_cpu >= NR_CPUS) if (next_cpu >= NR_CPUS)
next_cpu = 0; /* nothing else, assign monarch */ next_cpu = 0; /* nothing else, assign monarch */
return cpu_data[next_cpu].txn_addr; return txn_affinity_addr(virt_irq, next_cpu);
} }
@ -250,10 +303,11 @@ void do_cpu_irq_mask(struct pt_regs *regs)
irq_enter(); irq_enter();
/* /*
* Only allow interrupt processing to be interrupted by the * Don't allow TIMER or IPI nested interrupts.
* timer tick * Allowing any single interrupt to nest can lead to that CPU
* handling interrupts with all enabled interrupts unmasked.
*/ */
set_eiem(EIEM_MASK(TIMER_IRQ)); set_eiem(0UL);
/* 1) only process IRQs that are enabled/unmasked (cpu_eiem) /* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
* 2) We loop here on EIRR contents in order to avoid * 2) We loop here on EIRR contents in order to avoid
@ -267,23 +321,41 @@ void do_cpu_irq_mask(struct pt_regs *regs)
if (!eirr_val) if (!eirr_val)
break; break;
if (eirr_val & EIEM_MASK(TIMER_IRQ))
set_eiem(0);
mtctl(eirr_val, 23); /* reset bits we are going to process */ mtctl(eirr_val, 23); /* reset bits we are going to process */
/* Work our way from MSb to LSb...same order we alloc EIRs */ /* Work our way from MSb to LSb...same order we alloc EIRs */
for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) { for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
#ifdef CONFIG_SMP
cpumask_t dest = irq_affinity[irq];
#endif
if (!(bit & eirr_val)) if (!(bit & eirr_val))
continue; continue;
/* clear bit in mask - can exit loop sooner */ /* clear bit in mask - can exit loop sooner */
eirr_val &= ~bit; eirr_val &= ~bit;
#ifdef CONFIG_SMP
/* FIXME: because generic set affinity mucks
* with the affinity before sending it to us
* we can get the situation where the affinity is
* wrong for our CPU type interrupts */
if (irq != TIMER_IRQ && irq != IPI_IRQ &&
!cpu_isset(smp_processor_id(), dest)) {
int cpu = first_cpu(dest);
printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
irq, smp_processor_id(), cpu);
gsc_writel(irq + CPU_IRQ_BASE,
cpu_data[cpu].hpa);
continue;
}
#endif
__do_IRQ(irq, regs); __do_IRQ(irq, regs);
} }
} }
set_eiem(cpu_eiem);
set_eiem(cpu_eiem); /* restore original mask */
irq_exit(); irq_exit();
} }
@ -291,12 +363,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
static struct irqaction timer_action = { static struct irqaction timer_action = {
.handler = timer_interrupt, .handler = timer_interrupt,
.name = "timer", .name = "timer",
.flags = SA_INTERRUPT,
}; };
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static struct irqaction ipi_action = { static struct irqaction ipi_action = {
.handler = ipi_interrupt, .handler = ipi_interrupt,
.name = "IPI", .name = "IPI",
.flags = SA_INTERRUPT,
}; };
#endif #endif

View File

@ -196,8 +196,7 @@ static int perf_open(struct inode *inode, struct file *file);
static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos); static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos); loff_t *ppos);
static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
unsigned long arg);
static void perf_start_counters(void); static void perf_start_counters(void);
static int perf_stop_counters(uint32_t *raddr); static int perf_stop_counters(uint32_t *raddr);
static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num); static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
@ -438,48 +437,56 @@ static void perf_patch_images(void)
* must be running on the processor that you wish to change. * must be running on the processor that you wish to change.
*/ */
static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
unsigned long arg)
{ {
long error_start; long error_start;
uint32_t raddr[4]; uint32_t raddr[4];
int error = 0;
lock_kernel();
switch (cmd) { switch (cmd) {
case PA_PERF_ON: case PA_PERF_ON:
/* Start the counters */ /* Start the counters */
perf_start_counters(); perf_start_counters();
return 0; break;
case PA_PERF_OFF: case PA_PERF_OFF:
error_start = perf_stop_counters(raddr); error_start = perf_stop_counters(raddr);
if (error_start != 0) { if (error_start != 0) {
printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start); printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
return -EFAULT; error = -EFAULT;
break;
} }
/* copy out the Counters */ /* copy out the Counters */
if (copy_to_user((void __user *)arg, raddr, if (copy_to_user((void __user *)arg, raddr,
sizeof (raddr)) != 0) { sizeof (raddr)) != 0) {
return -EFAULT; error = -EFAULT;
break;
} }
return 0; break;
case PA_PERF_VERSION: case PA_PERF_VERSION:
/* Return the version # */ /* Return the version # */
return put_user(PERF_VERSION, (int *)arg); error = put_user(PERF_VERSION, (int *)arg);
break;
default: default:
break; error = -ENOTTY;
} }
return -ENOTTY;
unlock_kernel();
return error;
} }
static struct file_operations perf_fops = { static struct file_operations perf_fops = {
.llseek = no_llseek, .llseek = no_llseek,
.read = perf_read, .read = perf_read,
.write = perf_write, .write = perf_write,
.ioctl = perf_ioctl, .unlocked_ioctl = perf_ioctl,
.compat_ioctl = perf_ioctl,
.open = perf_open, .open = perf_open,
.release = perf_release .release = perf_release
}; };

View File

@ -264,6 +264,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* sigkill. perhaps it should be put in the status * sigkill. perhaps it should be put in the status
* that it wants to exit. * that it wants to exit.
*/ */
ret = 0;
DBG("sys_ptrace(KILL)\n"); DBG("sys_ptrace(KILL)\n");
if (child->exit_state == EXIT_ZOMBIE) /* already dead */ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
goto out_tsk; goto out_tsk;
@ -344,11 +345,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_GETEVENTMSG: case PTRACE_GETEVENTMSG:
ret = put_user(child->ptrace_message, (unsigned int __user *) data); ret = put_user(child->ptrace_message, (unsigned int __user *) data);
goto out; goto out_tsk;
default: default:
ret = ptrace_request(child, request, addr, data); ret = ptrace_request(child, request, addr, data);
goto out; goto out_tsk;
} }
out_wake_notrap: out_wake_notrap:

View File

@ -296,7 +296,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
struct rt_sigframe __user *frame; struct rt_sigframe __user *frame;
unsigned long rp, usp; unsigned long rp, usp;
unsigned long haddr, sigframe_size; unsigned long haddr, sigframe_size;
struct siginfo si;
int err = 0; int err = 0;
#ifdef __LP64__ #ifdef __LP64__
compat_int_t compat_val; compat_int_t compat_val;

View File

@ -181,12 +181,19 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while (ops) { while (ops) {
unsigned long which = ffz(~ops); unsigned long which = ffz(~ops);
ops &= ~(1 << which);
switch (which) { switch (which) {
case IPI_NOP:
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
#endif /* kDEBUG */
break;
case IPI_RESCHEDULE: case IPI_RESCHEDULE:
#if (kDEBUG>=100) #if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu); printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
#endif /* kDEBUG */ #endif /* kDEBUG */
ops &= ~(1 << IPI_RESCHEDULE);
/* /*
* Reschedule callback. Everything to be * Reschedule callback. Everything to be
* done is done by the interrupt return path. * done is done by the interrupt return path.
@ -197,7 +204,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100) #if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu); printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
#endif /* kDEBUG */ #endif /* kDEBUG */
ops &= ~(1 << IPI_CALL_FUNC);
{ {
volatile struct smp_call_struct *data; volatile struct smp_call_struct *data;
void (*func)(void *info); void (*func)(void *info);
@ -231,7 +237,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100) #if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu); printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
#endif /* kDEBUG */ #endif /* kDEBUG */
ops &= ~(1 << IPI_CPU_START);
#ifdef ENTRY_SYS_CPUS #ifdef ENTRY_SYS_CPUS
p->state = STATE_RUNNING; p->state = STATE_RUNNING;
#endif #endif
@ -241,7 +246,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100) #if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu); printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
#endif /* kDEBUG */ #endif /* kDEBUG */
ops &= ~(1 << IPI_CPU_STOP);
#ifdef ENTRY_SYS_CPUS #ifdef ENTRY_SYS_CPUS
#else #else
halt_processor(); halt_processor();
@ -252,13 +256,11 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100) #if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu); printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
#endif /* kDEBUG */ #endif /* kDEBUG */
ops &= ~(1 << IPI_CPU_TEST);
break; break;
default: default:
printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
this_cpu, which); this_cpu, which);
ops &= ~(1 << which);
return IRQ_NONE; return IRQ_NONE;
} /* Switch */ } /* Switch */
} /* while (ops) */ } /* while (ops) */
@ -312,6 +314,12 @@ smp_send_start(void) { send_IPI_allbutself(IPI_CPU_START); }
void void
smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); } smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
void
smp_send_all_nop(void)
{
send_IPI_allbutself(IPI_NOP);
}
/** /**
* Run a function on all other CPUs. * Run a function on all other CPUs.
@ -338,6 +346,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
/* Can deadlock when called with interrupts disabled */ /* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled()); WARN_ON(irqs_disabled());
/* can also deadlock if IPIs are disabled */
WARN_ON((get_eiem() & (1UL<<(CPU_IRQ_MAX - IPI_IRQ))) == 0);
data.func = func; data.func = func;
data.info = info; data.info = info;

View File

@ -164,7 +164,7 @@ linux_gateway_entry:
#endif #endif
STREG %r2, TASK_PT_GR30(%r1) /* ... and save it */ STREG %r2, TASK_PT_GR30(%r1) /* ... and save it */
STREG %r20, TASK_PT_GR20(%r1) STREG %r20, TASK_PT_GR20(%r1) /* Syscall number */
STREG %r21, TASK_PT_GR21(%r1) STREG %r21, TASK_PT_GR21(%r1)
STREG %r22, TASK_PT_GR22(%r1) STREG %r22, TASK_PT_GR22(%r1)
STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */ STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */
@ -527,6 +527,7 @@ lws_compare_and_swap:
We *must* giveup this call and fail. We *must* giveup this call and fail.
*/ */
ldw 4(%sr2,%r20), %r28 /* Load thread register */ ldw 4(%sr2,%r20), %r28 /* Load thread register */
/* WARNING: If cr27 cycles to the same value we have problems */
mfctl %cr27, %r21 /* Get current thread register */ mfctl %cr27, %r21 /* Get current thread register */
cmpb,<>,n %r21, %r28, cas_lock /* Called recursive? */ cmpb,<>,n %r21, %r28, cas_lock /* Called recursive? */
b lws_exit /* Return error! */ b lws_exit /* Return error! */

View File

@ -40,7 +40,7 @@
#endif #endif
unsigned long pci_probe_only = 1; unsigned long pci_probe_only = 1;
unsigned long pci_assign_all_buses = 0; int pci_assign_all_buses = 0;
/* /*
* legal IO pages under MAX_ISA_PORT. This is to ensure we don't touch * legal IO pages under MAX_ISA_PORT. This is to ensure we don't touch
@ -55,11 +55,6 @@ static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus); static void do_bus_setup(struct pci_bus *bus);
#endif #endif
unsigned int pcibios_assign_all_busses(void)
{
return pci_assign_all_buses;
}
/* pci_io_base -- the base address from which io bars are offsets. /* pci_io_base -- the base address from which io bars are offsets.
* This is the lowest I/O base address (so bar values are always positive), * This is the lowest I/O base address (so bar values are always positive),
* and it *must* be the start of ISA space if an ISA bus exists because * and it *must* be the start of ISA space if an ISA bus exists because
@ -1186,17 +1181,6 @@ void phbs_remap_io(void)
remap_bus_range(hose->bus); remap_bus_range(hose->bus);
} }
/*
* ppc64 can have multifunction devices that do not respond to function 0.
* In this case we must scan all functions.
* XXX this can go now, we use the OF device tree in all the
* cases that caused problems. -- paulus
*/
int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
{
return 0;
}
static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
{ {
struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pci_controller *hose = pci_bus_to_host(dev->bus);

View File

@ -146,9 +146,6 @@ EXPORT_SYMBOL(pci_bus_io_base);
EXPORT_SYMBOL(pci_bus_io_base_phys); EXPORT_SYMBOL(pci_bus_io_base_phys);
EXPORT_SYMBOL(pci_bus_mem_base_phys); EXPORT_SYMBOL(pci_bus_mem_base_phys);
EXPORT_SYMBOL(pci_bus_to_hose); EXPORT_SYMBOL(pci_bus_to_hose);
EXPORT_SYMBOL(pci_resource_to_bus);
EXPORT_SYMBOL(pci_phys_to_bus);
EXPORT_SYMBOL(pci_bus_to_phys);
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
#ifdef CONFIG_NOT_COHERENT_CACHE #ifdef CONFIG_NOT_COHERENT_CACHE

View File

@ -36,8 +36,9 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
#include <asm/ptrace-common.h> #include "ptrace-common.h"
#endif #endif
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32

View File

@ -33,7 +33,8 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/ptrace-common.h>
#include "ptrace-common.h"
/* /*
* does not yet catch signals sent when the child dies. * does not yet catch signals sent when the child dies.

View File

@ -14,9 +14,10 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/imalloc.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include "mmu_decl.h"
static DECLARE_MUTEX(imlist_sem); static DECLARE_MUTEX(imlist_sem);
struct vm_struct * imlist = NULL; struct vm_struct * imlist = NULL;

View File

@ -64,7 +64,8 @@
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/vdso.h> #include <asm/vdso.h>
#include <asm/imalloc.h>
#include "mmu_decl.h"
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) printk(fmt) #define DBG(fmt...) printk(fmt)

View File

@ -33,7 +33,6 @@ extern void invalidate_tlbcam_entry(int index);
extern int __map_without_bats; extern int __map_without_bats;
extern unsigned long ioremap_base; extern unsigned long ioremap_base;
extern unsigned long ioremap_bot;
extern unsigned int rtas_data, rtas_size; extern unsigned int rtas_data, rtas_size;
extern PTE *Hash, *Hash_end; extern PTE *Hash, *Hash_end;
@ -42,6 +41,7 @@ extern unsigned long Hash_size, Hash_mask;
extern unsigned int num_tlbcam_entries; extern unsigned int num_tlbcam_entries;
#endif #endif
extern unsigned long ioremap_bot;
extern unsigned long __max_low_memory; extern unsigned long __max_low_memory;
extern unsigned long __initial_memory_limit; extern unsigned long __initial_memory_limit;
extern unsigned long total_memory; extern unsigned long total_memory;
@ -84,4 +84,16 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
else else
_tlbie(va); _tlbie(va);
} }
#else /* CONFIG_PPC64 */
/* imalloc region types */
#define IM_REGION_UNUSED 0x1
#define IM_REGION_SUBSET 0x2
#define IM_REGION_EXISTS 0x4
#define IM_REGION_OVERLAP 0x8
#define IM_REGION_SUPERSET 0x10
extern struct vm_struct * im_get_free_area(unsigned long size);
extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
int region_type);
extern void im_free(void *addr);
#endif #endif

View File

@ -64,7 +64,8 @@
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/vdso.h> #include <asm/vdso.h>
#include <asm/imalloc.h>
#include "mmu_decl.h"
unsigned long ioremap_bot = IMALLOC_BASE; unsigned long ioremap_bot = IMALLOC_BASE;
static unsigned long phbs_io_bot = PHBS_IO_BASE; static unsigned long phbs_io_bot = PHBS_IO_BASE;

View File

@ -34,6 +34,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/compiler.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/atomic.h> #include <asm/atomic.h>
@ -631,8 +632,9 @@ void smp_core99_give_timebase(void)
mb(); mb();
/* wait for the secondary to have taken it */ /* wait for the secondary to have taken it */
for (t = 100000; t > 0 && sec_tb_reset; --t) /* note: can't use udelay here, since it needs the timebase running */
udelay(10); for (t = 10000000; t > 0 && sec_tb_reset; --t)
barrier();
if (sec_tb_reset) if (sec_tb_reset)
/* XXX BUG_ON here? */ /* XXX BUG_ON here? */
printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");

View File

@ -361,7 +361,8 @@ static void mpic_enable_irq(unsigned int irq)
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK); mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */ /* make sure mask gets to controller before we return to user */
do { do {
@ -381,7 +382,8 @@ static void mpic_disable_irq(unsigned int irq)
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK); mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */ /* make sure mask gets to controller before we return to user */
do { do {
@ -735,12 +737,13 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
spin_lock_irqsave(&mpic_lock, flags); spin_lock_irqsave(&mpic_lock, flags);
if (is_ipi) { if (is_ipi) {
reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK; reg = mpic_ipi_read(irq - mpic->ipi_offset) &
~MPIC_VECPRI_PRIORITY_MASK;
mpic_ipi_write(irq - mpic->ipi_offset, mpic_ipi_write(irq - mpic->ipi_offset,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} else { } else {
reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI) reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
& MPIC_VECPRI_PRIORITY_MASK; & ~MPIC_VECPRI_PRIORITY_MASK;
mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI, mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} }

View File

@ -1,6 +1,4 @@
/* /*
* linux/drivers/block/as-iosched.c
*
* Anticipatory & deadline i/o scheduler. * Anticipatory & deadline i/o scheduler.
* *
* Copyright (C) 2002 Jens Axboe <axboe@suse.de> * Copyright (C) 2002 Jens Axboe <axboe@suse.de>
@ -1373,10 +1371,6 @@ static void as_add_request(request_queue_t *q, struct request *rq)
struct as_rq *alias; struct as_rq *alias;
int data_dir; int data_dir;
if (arq->state != AS_RQ_PRESCHED) {
printk("arq->state: %d\n", arq->state);
WARN_ON(1);
}
arq->state = AS_RQ_NEW; arq->state = AS_RQ_NEW;
if (rq_data_dir(arq->request) == READ if (rq_data_dir(arq->request) == READ

View File

@ -1,6 +1,4 @@
/* /*
* linux/drivers/block/cfq-iosched.c
*
* CFQ, or complete fairness queueing, disk scheduler. * CFQ, or complete fairness queueing, disk scheduler.
* *
* Based on ideas from a previously unfinished io * Based on ideas from a previously unfinished io

View File

@ -1,6 +1,4 @@
/* /*
* linux/drivers/block/deadline-iosched.c
*
* Deadline i/o scheduler. * Deadline i/o scheduler.
* *
* Copyright (C) 2002 Jens Axboe <axboe@suse.de> * Copyright (C) 2002 Jens Axboe <axboe@suse.de>

View File

@ -1,6 +1,4 @@
/* /*
* linux/drivers/block/elevator.c
*
* Block device elevator/IO-scheduler. * Block device elevator/IO-scheduler.
* *
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE

View File

@ -1,6 +1,4 @@
/* /*
* linux/drivers/block/ll_rw_blk.c
*
* Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1994, Karl Keyte: Added support for disk statistics * Copyright (C) 1994, Karl Keyte: Added support for disk statistics
* Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE * Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE

View File

@ -1017,10 +1017,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
status = -ENOMEM; status = -ENOMEM;
goto cleanup1; goto cleanup1;
} }
if (ioc->Request.Type.Direction == XFER_WRITE && if (ioc->Request.Type.Direction == XFER_WRITE) {
copy_from_user(buff[sg_used], data_ptr, sz)) { if (copy_from_user(buff[sg_used], data_ptr, sz)) {
status = -ENOMEM; status = -ENOMEM;
goto cleanup1; goto cleanup1;
}
} else { } else {
memset(buff[sg_used], 0, sz); memset(buff[sg_used], 0, sz);
} }
@ -1138,8 +1139,15 @@ static int revalidate_allvol(ctlr_info_t *host)
for(i=0; i< NWD; i++) { for(i=0; i< NWD; i++) {
struct gendisk *disk = host->gendisk[i]; struct gendisk *disk = host->gendisk[i];
if (disk->flags & GENHD_FL_UP) if (disk) {
del_gendisk(disk); request_queue_t *q = disk->queue;
if (disk->flags & GENHD_FL_UP)
del_gendisk(disk);
if (q)
blk_cleanup_queue(q);
put_disk(disk);
}
} }
/* /*
@ -1453,10 +1461,13 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
* allows us to delete disk zero but keep the controller registered. * allows us to delete disk zero but keep the controller registered.
*/ */
if (h->gendisk[0] != disk){ if (h->gendisk[0] != disk){
if (disk->flags & GENHD_FL_UP){ if (disk) {
blk_cleanup_queue(disk->queue); request_queue_t *q = disk->queue;
del_gendisk(disk); if (disk->flags & GENHD_FL_UP)
drv->queue = NULL; del_gendisk(disk);
if (q)
blk_cleanup_queue(q);
put_disk(disk);
} }
} }
@ -3225,9 +3236,14 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
/* remove it from the disk list */ /* remove it from the disk list */
for (j = 0; j < NWD; j++) { for (j = 0; j < NWD; j++) {
struct gendisk *disk = hba[i]->gendisk[j]; struct gendisk *disk = hba[i]->gendisk[j];
if (disk->flags & GENHD_FL_UP) { if (disk) {
del_gendisk(disk); request_queue_t *q = disk->queue;
blk_cleanup_queue(disk->queue);
if (disk->flags & GENHD_FL_UP)
del_gendisk(disk);
if (q)
blk_cleanup_queue(q);
put_disk(disk);
} }
} }

View File

@ -416,7 +416,7 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data
} }
static struct aper_size_info_32 uli_sizes[7] = static const struct aper_size_info_32 uli_sizes[7] =
{ {
{256, 65536, 6, 10}, {256, 65536, 6, 10},
{128, 32768, 5, 9}, {128, 32768, 5, 9},
@ -470,7 +470,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
} }
static struct aper_size_info_32 nforce3_sizes[5] = static const struct aper_size_info_32 nforce3_sizes[5] =
{ {
{512, 131072, 7, 0x00000000 }, {512, 131072, 7, 0x00000000 },
{256, 65536, 6, 0x00000008 }, {256, 65536, 6, 0x00000008 },

View File

@ -97,7 +97,7 @@ void agp_backend_release(struct agp_bridge_data *bridge)
EXPORT_SYMBOL(agp_backend_release); EXPORT_SYMBOL(agp_backend_release);
static struct { int mem, agp; } maxes_table[] = { static const struct { int mem, agp; } maxes_table[] = {
{0, 0}, {0, 0},
{32, 4}, {32, 4},
{64, 28}, {64, 28},

View File

@ -371,6 +371,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
.device_id = PCI_DEVICE_ID_VIA_3296_0, .device_id = PCI_DEVICE_ID_VIA_3296_0,
.chipset_name = "P4M800", .chipset_name = "P4M800",
}, },
/* P4M800CE */
{
.device_id = PCI_DEVICE_ID_VIA_P4M800CE,
.chipset_name = "P4M800CE",
},
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
@ -511,6 +516,7 @@ static struct pci_device_id agp_via_pci_table[] = {
ID(PCI_DEVICE_ID_VIA_3269_0), ID(PCI_DEVICE_ID_VIA_3269_0),
ID(PCI_DEVICE_ID_VIA_83_87XX_1), ID(PCI_DEVICE_ID_VIA_83_87XX_1),
ID(PCI_DEVICE_ID_VIA_3296_0), ID(PCI_DEVICE_ID_VIA_3296_0),
ID(PCI_DEVICE_ID_VIA_P4M800CE),
{ } { }
}; };

View File

@ -36,8 +36,6 @@
#include <asm/hardware.h> /* Pick up IXP2000-specific bits */ #include <asm/hardware.h> /* Pick up IXP2000-specific bits */
#include <asm/arch/gpio.h> #include <asm/arch/gpio.h>
static struct device_driver ixp2000_i2c_driver;
static inline int ixp2000_scl_pin(void *data) static inline int ixp2000_scl_pin(void *data)
{ {
return ((struct ixp2000_i2c_pins*)data)->scl_pin; return ((struct ixp2000_i2c_pins*)data)->scl_pin;
@ -120,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.timeout = 100; drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP2000, drv_data->adapter.id = I2C_HW_B_IXP2000,
strlcpy(drv_data->adapter.name, ixp2000_i2c_driver.name, strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE); I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data, drv_data->adapter.algo_data = &drv_data->algo_data,
@ -132,7 +130,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
gpio_line_set(gpio->sda_pin, 0); gpio_line_set(gpio->sda_pin, 0);
if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) { if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) {
dev_err(dev, "Could not install, error %d\n", err); dev_err(&plat_dev->dev, "Could not install, error %d\n", err);
kfree(drv_data); kfree(drv_data);
return err; return err;
} }

View File

@ -35,8 +35,6 @@
#include <asm/hardware.h> /* Pick up IXP4xx-specific bits */ #include <asm/hardware.h> /* Pick up IXP4xx-specific bits */
static struct platform_driver ixp4xx_i2c_driver;
static inline int ixp4xx_scl_pin(void *data) static inline int ixp4xx_scl_pin(void *data)
{ {
return ((struct ixp4xx_i2c_pins*)data)->scl_pin; return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
@ -128,7 +126,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.timeout = 100; drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP4XX; drv_data->adapter.id = I2C_HW_B_IXP4XX;
strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.driver.name, strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE); I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data; drv_data->adapter.algo_data = &drv_data->algo_data;
@ -140,8 +138,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
gpio_line_set(gpio->sda_pin, 0); gpio_line_set(gpio->sda_pin, 0);
if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
printk(KERN_ERR "ERROR: Could not install %s\n", printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id);
plat_dev->dev.bus_id);
kfree(drv_data); kfree(drv_data);
return err; return err;

View File

@ -625,7 +625,7 @@ config BLK_DEV_NS87415
tristate "NS87415 chipset support" tristate "NS87415 chipset support"
help help
This driver adds detection and support for the NS87415 chip This driver adds detection and support for the NS87415 chip
(used in SPARC64, among others). (used mainly on SPARC64 and PA-RISC machines).
Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>. Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.

View File

@ -3328,8 +3328,8 @@ static ide_proc_entry_t idecd_proc[] = {
#endif #endif
static ide_driver_t ide_cdrom_driver = { static ide_driver_t ide_cdrom_driver = {
.owner = THIS_MODULE,
.gen_driver = { .gen_driver = {
.owner = THIS_MODULE,
.name = "ide-cdrom", .name = "ide-cdrom",
.bus = &ide_bus_type, .bus = &ide_bus_type,
.probe = ide_cd_probe, .probe = ide_cd_probe,
@ -3510,8 +3510,8 @@ static void __exit ide_cdrom_exit(void)
{ {
driver_unregister(&ide_cdrom_driver.gen_driver); driver_unregister(&ide_cdrom_driver.gen_driver);
} }
static int ide_cdrom_init(void) static int __init ide_cdrom_init(void)
{ {
return driver_register(&ide_cdrom_driver.gen_driver); return driver_register(&ide_cdrom_driver.gen_driver);
} }

View File

@ -1089,8 +1089,8 @@ static void ide_device_shutdown(struct device *dev)
} }
static ide_driver_t idedisk_driver = { static ide_driver_t idedisk_driver = {
.owner = THIS_MODULE,
.gen_driver = { .gen_driver = {
.owner = THIS_MODULE,
.name = "ide-disk", .name = "ide-disk",
.bus = &ide_bus_type, .bus = &ide_bus_type,
.probe = ide_disk_probe, .probe = ide_disk_probe,
@ -1266,7 +1266,7 @@ static void __exit idedisk_exit (void)
driver_unregister(&idedisk_driver.gen_driver); driver_unregister(&idedisk_driver.gen_driver);
} }
static int idedisk_init (void) static int __init idedisk_init(void)
{ {
return driver_register(&idedisk_driver.gen_driver); return driver_register(&idedisk_driver.gen_driver);
} }

View File

@ -1925,8 +1925,8 @@ static ide_proc_entry_t idefloppy_proc[] = {
static int ide_floppy_probe(struct device *); static int ide_floppy_probe(struct device *);
static ide_driver_t idefloppy_driver = { static ide_driver_t idefloppy_driver = {
.owner = THIS_MODULE,
.gen_driver = { .gen_driver = {
.owner = THIS_MODULE,
.name = "ide-floppy", .name = "ide-floppy",
.bus = &ide_bus_type, .bus = &ide_bus_type,
.probe = ide_floppy_probe, .probe = ide_floppy_probe,
@ -2191,10 +2191,7 @@ static void __exit idefloppy_exit (void)
driver_unregister(&idefloppy_driver.gen_driver); driver_unregister(&idefloppy_driver.gen_driver);
} }
/* static int __init idefloppy_init(void)
* idefloppy_init will register the driver for each floppy.
*/
static int idefloppy_init (void)
{ {
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n"); printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
return driver_register(&idefloppy_driver.gen_driver); return driver_register(&idefloppy_driver.gen_driver);

View File

@ -1629,12 +1629,6 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
* for the new rq to be completed. This is VERY DANGEROUS, and is * for the new rq to be completed. This is VERY DANGEROUS, and is
* intended for careful use by the ATAPI tape/cdrom driver code. * intended for careful use by the ATAPI tape/cdrom driver code.
* *
* If action is ide_next, then the rq is queued immediately after
* the currently-being-processed-request (if any), and the function
* returns without waiting for the new rq to be completed. As above,
* This is VERY DANGEROUS, and is intended for careful use by the
* ATAPI tape/cdrom driver code.
*
* If action is ide_end, then the rq is queued at the end of the * If action is ide_end, then the rq is queued at the end of the
* request queue, and the function returns immediately without waiting * request queue, and the function returns immediately without waiting
* for the new rq to be completed. This is again intended for careful * for the new rq to be completed. This is again intended for careful

View File

@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
{ {
u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */ u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */
if (on && drive->media == ide_disk) { if (!PCI_DMA_BUS_IS_PHYS) {
if (!PCI_DMA_BUS_IS_PHYS) addr = BLK_BOUNCE_ANY;
addr = BLK_BOUNCE_ANY; } else if (on && drive->media == ide_disk) {
else if (HWIF(drive)->pci_dev) if (HWIF(drive)->pci_dev)
addr = HWIF(drive)->pci_dev->dma_mask; addr = HWIF(drive)->pci_dev->dma_mask;
} }

View File

@ -4748,8 +4748,8 @@ static ide_proc_entry_t idetape_proc[] = {
static int ide_tape_probe(struct device *); static int ide_tape_probe(struct device *);
static ide_driver_t idetape_driver = { static ide_driver_t idetape_driver = {
.owner = THIS_MODULE,
.gen_driver = { .gen_driver = {
.owner = THIS_MODULE,
.name = "ide-tape", .name = "ide-tape",
.bus = &ide_bus_type, .bus = &ide_bus_type,
.probe = ide_tape_probe, .probe = ide_tape_probe,
@ -4916,10 +4916,7 @@ static void __exit idetape_exit (void)
unregister_chrdev(IDETAPE_MAJOR, "ht"); unregister_chrdev(IDETAPE_MAJOR, "ht");
} }
/* static int __init idetape_init(void)
* idetape_init will register the driver for each tape.
*/
static int idetape_init (void)
{ {
int error = 1; int error = 1;
idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape"); idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");

View File

@ -51,8 +51,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
#define DEBUG_TASKFILE 0 /* unset when fixed */
static void ata_bswap_data (void *buffer, int wcount) static void ata_bswap_data (void *buffer, int wcount)
{ {
u16 *p = buffer; u16 *p = buffer;
@ -765,9 +763,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
task_struct_t *taskfile = (task_struct_t *) task->tfRegister; task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
#if DEBUG_TASKFILE
u8 status;
#endif
if (task->data_phase == TASKFILE_MULTI_IN || if (task->data_phase == TASKFILE_MULTI_IN ||
task->data_phase == TASKFILE_MULTI_OUT) { task->data_phase == TASKFILE_MULTI_OUT) {
@ -778,19 +773,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
} }
/* /*
* (ks) Check taskfile in/out flags. * (ks) Check taskfile in flags.
* If set, then execute as it is defined. * If set, then execute as it is defined.
* If not set, then define default settings. * If not set, then define default settings.
* The default values are: * The default values are:
* write and read all taskfile registers (except data) * read all taskfile registers (except data)
* write and read the hob registers (sector,nsector,lcyl,hcyl) * read the hob registers (sector, nsector, lcyl, hcyl)
*/ */
if (task->tf_out_flags.all == 0) {
task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
if (drive->addressing == 1)
task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
}
if (task->tf_in_flags.all == 0) { if (task->tf_in_flags.all == 0) {
task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->addressing == 1) if (drive->addressing == 1)
@ -803,16 +792,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
hwif->OUTB(drive->ctl, IDE_CONTROL_REG); hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
SELECT_MASK(drive, 0); SELECT_MASK(drive, 0);
#if DEBUG_TASKFILE
status = hwif->INB(IDE_STATUS_REG);
if (status & 0x80) {
printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
udelay(100);
status = hwif->INB(IDE_STATUS_REG);
printk("flagged_taskfile -> Status = %02x\n", status);
}
#endif
if (task->tf_out_flags.b.data) { if (task->tf_out_flags.b.data) {
u16 data = taskfile->data + (hobfile->data << 8); u16 data = taskfile->data + (hobfile->data << 8);
hwif->OUTW(data, IDE_DATA_REG); hwif->OUTW(data, IDE_DATA_REG);

View File

@ -65,23 +65,6 @@ static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
#define BUSCLOCK(D) \ #define BUSCLOCK(D) \
((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D))) ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
#if 0
if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
(void) pci_read_config_byte(dev, 0x54, &art);
p += sprintf(p, "DMA Mode: %s(%s)",
(c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO",
(art&0x02)?"2":(art&0x01)?"1":"0");
p += sprintf(p, " %s(%s)",
(c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO",
(art&0x08)?"2":(art&0x04)?"1":"0");
p += sprintf(p, " %s(%s)",
(c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO",
(art&0x20)?"2":(art&0x10)?"1":"0");
p += sprintf(p, " %s(%s)\n",
(c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO",
(art&0x80)?"2":(art&0x40)?"1":"0");
} else {
#endif
/* /*
* TO DO: active tuning and correction of cards without a bios. * TO DO: active tuning and correction of cards without a bios.
@ -112,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
switch(hwif->pci_dev->device) { switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865:
case PCI_DEVICE_ID_ARTOP_ATP865R: case PCI_DEVICE_ID_ARTOP_ATP865R:
#if 0
mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3;
#else
mode = (hwif->INB(((hwif->channel) ? mode = (hwif->INB(((hwif->channel) ?
hwif->mate->dma_status : hwif->mate->dma_status :
hwif->dma_status)) & 0x10) ? 4 : 3; hwif->dma_status)) & 0x10) ? 4 : 3;
#endif
break; break;
case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860:
case PCI_DEVICE_ID_ARTOP_ATP860R: case PCI_DEVICE_ID_ARTOP_ATP860R:
@ -263,35 +242,9 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865:
case PCI_DEVICE_ID_ARTOP_ATP865R: case PCI_DEVICE_ID_ARTOP_ATP865R:
printk(" AEC62XX time out "); printk(" AEC62XX time out ");
#if 0
{
int i = 0;
u8 reg49h = 0;
pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, &reg49h);
for (i=0;i<256;i++)
pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10);
pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10);
}
return 0;
#endif
default: default:
break; break;
} }
#if 0
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 tmp1 = 0, tmp2 = 0, mode6 = 0;
pci_read_config_byte(dev, 0x44, &tmp1);
pci_read_config_byte(dev, 0x45, &tmp2);
printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2);
mode6 = HWIF(drive)->INB(((hwif->channel) ?
hwif->mate->dma_status :
hwif->dma_status));
printk(" AEC6280 133=%x ", (mode6 & 0x10));
}
#endif
return 0; return 0;
} }

View File

@ -876,10 +876,15 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{ {
static struct pci_device_id ati_rs100[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
{ },
};
ide_pci_device_t *d = &ali15x3_chipset; ide_pci_device_t *d = &ali15x3_chipset;
if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL)) if (pci_dev_present(ati_rs100))
printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n"); printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
#if defined(CONFIG_SPARC64) #if defined(CONFIG_SPARC64)
d->init_hwif = init_hwif_common_ali15x3; d->init_hwif = init_hwif_common_ali15x3;

View File

@ -222,10 +222,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
/* We must not grab the entire device, it has 'ISA' space in its /* We must not grab the entire device, it has 'ISA' space in its
BARS too and we will freak out other bits of the kernel */ BARS too and we will freak out other bits of the kernel */
if(pci_enable_device_bars(dev, 1<<2)) if (pci_enable_device_bars(dev, 1<<2)) {
{
printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name); printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
return 1; return -ENODEV;
} }
pci_set_master(dev); pci_set_master(dev);
if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {

View File

@ -6,7 +6,13 @@
* *
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
* *
* Documentation available under NDA only * Documentation for CMD680:
* http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
*
* Documentation for SiI 3112:
* http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
*
* Errata and other documentation only available under NDA.
* *
* *
* FAQ Items: * FAQ Items:

View File

@ -87,6 +87,7 @@ static const struct {
u8 chipset_family; u8 chipset_family;
u8 flags; u8 flags;
} SiSHostChipInfo[] = { } SiSHostChipInfo[] = {
{ "SiS965", PCI_DEVICE_ID_SI_965, ATA_133 },
{ "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 }, { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 },
{ "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 }, { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 },
{ "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 }, { "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 },

View File

@ -79,6 +79,7 @@ static struct via_isa_bridge {
u8 rev_max; u8 rev_max;
u16 flags; u16 flags;
} via_isa_bridges[] = { } via_isa_bridges[] = {
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@ -100,185 +101,14 @@ static struct via_isa_bridge {
{ NULL } { NULL }
}; };
static struct via_isa_bridge *via_config;
static unsigned int via_80w;
static unsigned int via_clock; static unsigned int via_clock;
static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
/* struct via82cxxx_dev
* VIA /proc entry.
*/
#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static u8 via_proc = 0;
static unsigned long via_base;
static struct pci_dev *bmide_dev, *isa_dev;
static char *via_control3[] = { "No limit", "64", "128", "192" };
#define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
#define via_print_drive(name, format, arg...)\
p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
/**
* via_get_info - generate via /proc file
* @buffer: buffer for data
* @addr: set to start of data to use
* @offset: current file offset
* @count: size of read
*
* Fills in buffer with the debugging/configuration information for
* the VIA chipset tuning and attached drives
*/
static int via_get_info(char *buffer, char **addr, off_t offset, int count)
{ {
int speed[4], cycle[4], setup[4], active[4], recover[4], den[4], struct via_isa_bridge *via_config;
uen[4], udma[4], umul[4], active8b[4], recover8b[4]; unsigned int via_80w;
struct pci_dev *dev = bmide_dev; };
unsigned int v, u, i;
int len;
u16 c, w;
u8 t, x;
char *p = buffer;
via_print("----------VIA BusMastering IDE Configuration"
"----------------");
via_print("Driver Version: 3.38");
via_print("South Bridge: VIA %s",
via_config->name);
pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
pci_read_config_byte(dev, PCI_REVISION_ID, &x);
via_print("Revision: ISA %#x IDE %#x", t, x);
via_print("Highest DMA rate: %s",
via_dma[via_config->flags & VIA_UDMA]);
via_print("BM-DMA base: %#lx", via_base);
via_print("PCI clock: %d.%dMHz",
via_clock / 1000, via_clock / 100 % 10);
pci_read_config_byte(dev, VIA_MISC_1, &t);
via_print("Master Read Cycle IRDY: %dws",
(t & 64) >> 6);
via_print("Master Write Cycle IRDY: %dws",
(t & 32) >> 5);
via_print("BM IDE Status Register Read Retry: %s",
(t & 8) ? "yes" : "no");
pci_read_config_byte(dev, VIA_MISC_3, &t);
via_print("Max DRDY Pulse Width: %s%s",
via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : "");
via_print("-----------------------Primary IDE"
"-------Secondary IDE------");
via_print("Read DMA FIFO flush: %10s%20s",
(t & 0x80) ? "yes" : "no", (t & 0x40) ? "yes" : "no");
via_print("End Sector FIFO flush: %10s%20s",
(t & 0x20) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
pci_read_config_byte(dev, VIA_IDE_CONFIG, &t);
via_print("Prefetch Buffer: %10s%20s",
(t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
via_print("Post Write Buffer: %10s%20s",
(t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
pci_read_config_byte(dev, VIA_IDE_ENABLE, &t);
via_print("Enabled: %10s%20s",
(t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8);
via_print("Simplex only: %10s%20s",
(c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
via_print("Cable Type: %10s%20s",
(via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w");
via_print("-------------------drive0----drive1"
"----drive2----drive3-----");
pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v);
pci_read_config_word(dev, VIA_8BIT_TIMING, &w);
if (via_config->flags & VIA_UDMA)
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
else u = 0;
for (i = 0; i < 4; i++) {
setup[i] = ((t >> ((3 - i) << 1)) & 0x3) + 1;
recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
active8b[i] = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
active[i] = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
recover[i] = ((v >> ((3 - i) << 3)) & 0xf) + 1;
udma[i] = ((u >> ((3 - i) << 3)) & 0x7) + 2;
umul[i] = ((u >> (((3 - i) & 2) << 3)) & 0x8) ? 1 : 2;
uen[i] = ((u >> ((3 - i) << 3)) & 0x20);
den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
speed[i] = 2 * via_clock / (active[i] + recover[i]);
cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock;
if (!uen[i] || !den[i])
continue;
switch (via_config->flags & VIA_UDMA) {
case VIA_UDMA_33:
speed[i] = 2 * via_clock / udma[i];
cycle[i] = 1000000 * udma[i] / via_clock;
break;
case VIA_UDMA_66:
speed[i] = 4 * via_clock / (udma[i] * umul[i]);
cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock;
break;
case VIA_UDMA_100:
speed[i] = 6 * via_clock / udma[i];
cycle[i] = 333333 * udma[i] / via_clock;
break;
case VIA_UDMA_133:
speed[i] = 8 * via_clock / udma[i];
cycle[i] = 250000 * udma[i] / via_clock;
break;
}
}
via_print_drive("Transfer Mode: ", "%10s",
den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
via_print_drive("Address Setup: ", "%8dns",
1000000 * setup[i] / via_clock);
via_print_drive("Cmd Active: ", "%8dns",
1000000 * active8b[i] / via_clock);
via_print_drive("Cmd Recovery: ", "%8dns",
1000000 * recover8b[i] / via_clock);
via_print_drive("Data Active: ", "%8dns",
1000000 * active[i] / via_clock);
via_print_drive("Data Recovery: ", "%8dns",
1000000 * recover[i] / via_clock);
via_print_drive("Cycle Time: ", "%8dns",
cycle[i]);
via_print_drive("Transfer Rate: ", "%4d.%dMB/s",
speed[i] / 1000, speed[i] / 100 % 10);
/* hoping it is less than 4K... */
len = (p - buffer) - offset;
*addr = buffer + offset;
return len > count ? count : len;
}
#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
/** /**
* via_set_speed - write timing registers * via_set_speed - write timing registers
@ -289,11 +119,13 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
* via_set_speed writes timing values to the chipset registers * via_set_speed writes timing values to the chipset registers
*/ */
static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
{ {
struct pci_dev *dev = hwif->pci_dev;
struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
u8 t; u8 t;
if (~via_config->flags & VIA_BAD_AST) { if (~vdev->via_config->flags & VIA_BAD_AST) {
pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
@ -305,7 +137,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
switch (via_config->flags & VIA_UDMA) { switch (vdev->via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
@ -329,6 +161,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
static int via_set_drive(ide_drive_t *drive, u8 speed) static int via_set_drive(ide_drive_t *drive, u8 speed)
{ {
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
struct ide_timing t, p; struct ide_timing t, p;
unsigned int T, UT; unsigned int T, UT;
@ -337,7 +170,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
T = 1000000000 / via_clock; T = 1000000000 / via_clock;
switch (via_config->flags & VIA_UDMA) { switch (vdev->via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: UT = T; break; case VIA_UDMA_33: UT = T; break;
case VIA_UDMA_66: UT = T/2; break; case VIA_UDMA_66: UT = T/2; break;
case VIA_UDMA_100: UT = T/3; break; case VIA_UDMA_100: UT = T/3; break;
@ -352,7 +185,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
} }
via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); via_set_speed(HWIF(drive), drive->dn, &t);
if (!drive->init_speed) if (!drive->init_speed)
drive->init_speed = speed; drive->init_speed = speed;
@ -390,20 +223,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
static int via82cxxx_ide_dma_check (ide_drive_t *drive) static int via82cxxx_ide_dma_check (ide_drive_t *drive)
{ {
u16 w80 = HWIF(drive)->udma_four; ide_hwif_t *hwif = HWIF(drive);
struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
u16 w80 = hwif->udma_four;
u16 speed = ide_find_best_mode(drive, u16 speed = ide_find_best_mode(drive,
XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
(via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
via_set_drive(drive, speed); via_set_drive(drive, speed);
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
return HWIF(drive)->ide_dma_on(drive); return hwif->ide_dma_on(drive);
return HWIF(drive)->ide_dma_off_quietly(drive); return hwif->ide_dma_off_quietly(drive);
}
static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
{
struct via_isa_bridge *via_config;
u8 t;
for (via_config = via_isa_bridges; via_config->id; via_config++)
if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
!!(via_config->flags & VIA_BAD_ID),
via_config->id, NULL))) {
pci_read_config_byte(*isa, PCI_REVISION_ID, &t);
if (t >= via_config->rev_min &&
t <= via_config->rev_max)
break;
}
return via_config;
} }
/** /**
@ -418,82 +272,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
{ {
struct pci_dev *isa = NULL; struct pci_dev *isa = NULL;
struct via_isa_bridge *via_config;
u8 t, v; u8 t, v;
unsigned int u; unsigned int u;
int i;
/* /*
* Find the ISA bridge to see how good the IDE is. * Find the ISA bridge to see how good the IDE is.
*/ */
via_config = via_config_find(&isa);
for (via_config = via_isa_bridges; via_config->id; via_config++)
if ((isa = pci_find_device(PCI_VENDOR_ID_VIA +
!!(via_config->flags & VIA_BAD_ID),
via_config->id, NULL))) {
pci_read_config_byte(isa, PCI_REVISION_ID, &t);
if (t >= via_config->rev_min &&
t <= via_config->rev_max)
break;
}
if (!via_config->id) { if (!via_config->id) {
printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
return -ENODEV; return -ENODEV;
} }
/* /*
* Check 80-wire cable presence and setup Clk66. * Setup or disable Clk66 if appropriate
*/ */
switch (via_config->flags & VIA_UDMA) { if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
/* Enable Clk66 */
case VIA_UDMA_66: pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
/* Enable Clk66 */ pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); } else if (via_config->flags & VIA_BAD_CLK66) {
pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
for (i = 24; i >= 0; i -= 8)
if (((u >> (i & 16)) & 8) &&
((u >> i) & 0x20) &&
(((u >> i) & 7) < 2)) {
/*
* 2x PCI clock and
* UDMA w/ < 3T/cycle
*/
via_80w |= (1 << (1 - (i >> 4)));
}
break;
case VIA_UDMA_100:
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
for (i = 24; i >= 0; i -= 8)
if (((u >> i) & 0x10) ||
(((u >> i) & 0x20) &&
(((u >> i) & 7) < 4))) {
/* BIOS 80-wire bit or
* UDMA w/ < 60ns/cycle
*/
via_80w |= (1 << (1 - (i >> 4)));
}
break;
case VIA_UDMA_133:
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
for (i = 24; i >= 0; i -= 8)
if (((u >> i) & 0x10) ||
(((u >> i) & 0x20) &&
(((u >> i) & 7) < 6))) {
/* BIOS 80-wire bit or
* UDMA w/ < 60ns/cycle
*/
via_80w |= (1 << (1 - (i >> 4)));
}
break;
}
/* Disable Clk66 */
if (via_config->flags & VIA_BAD_CLK66) {
/* Would cause trouble on 596a and 686 */ /* Would cause trouble on 596a and 686 */
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008); pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
@ -560,26 +360,78 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
via_dma[via_config->flags & VIA_UDMA], via_dma[via_config->flags & VIA_UDMA],
pci_name(dev)); pci_name(dev));
/*
* Setup /proc/ide/via entry.
*/
#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
if (!via_proc) {
via_base = pci_resource_start(dev, 4);
bmide_dev = dev;
isa_dev = isa;
ide_pci_create_host_proc("via", via_get_info);
via_proc = 1;
}
#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
return 0; return 0;
} }
/*
* Check and handle 80-wire cable presence
*/
static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev)
{
unsigned int u;
int i;
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
switch (vdev->via_config->flags & VIA_UDMA) {
case VIA_UDMA_66:
for (i = 24; i >= 0; i -= 8)
if (((u >> (i & 16)) & 8) &&
((u >> i) & 0x20) &&
(((u >> i) & 7) < 2)) {
/*
* 2x PCI clock and
* UDMA w/ < 3T/cycle
*/
vdev->via_80w |= (1 << (1 - (i >> 4)));
}
break;
case VIA_UDMA_100:
for (i = 24; i >= 0; i -= 8)
if (((u >> i) & 0x10) ||
(((u >> i) & 0x20) &&
(((u >> i) & 7) < 4))) {
/* BIOS 80-wire bit or
* UDMA w/ < 60ns/cycle
*/
vdev->via_80w |= (1 << (1 - (i >> 4)));
}
break;
case VIA_UDMA_133:
for (i = 24; i >= 0; i -= 8)
if (((u >> i) & 0x10) ||
(((u >> i) & 0x20) &&
(((u >> i) & 7) < 6))) {
/* BIOS 80-wire bit or
* UDMA w/ < 60ns/cycle
*/
vdev->via_80w |= (1 << (1 - (i >> 4)));
}
break;
}
}
static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
{ {
struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev),
GFP_KERNEL);
struct pci_dev *isa = NULL;
int i; int i;
if (vdev == NULL) {
printk(KERN_ERR "VP_IDE: out of memory :(\n");
return;
}
memset(vdev, 0, sizeof(struct via82cxxx_dev));
ide_set_hwifdata(hwif, vdev);
vdev->via_config = via_config_find(&isa);
via_cable_detect(hwif->pci_dev, vdev);
hwif->autodma = 0; hwif->autodma = 0;
hwif->tuneproc = &via82cxxx_tune_drive; hwif->tuneproc = &via82cxxx_tune_drive;
@ -594,7 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1; hwif->drives[i].io_32bit = 1;
hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1; hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
hwif->drives[i].autotune = 1; hwif->drives[i].autotune = 1;
hwif->drives[i].dn = hwif->channel * 2 + i; hwif->drives[i].dn = hwif->channel * 2 + i;
} }
@ -608,7 +460,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->swdma_mask = 0x07; hwif->swdma_mask = 0x07;
if (!hwif->udma_four) if (!hwif->udma_four)
hwif->udma_four = (via_80w >> hwif->channel) & 1; hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
hwif->ide_dma_check = &via82cxxx_ide_dma_check; hwif->ide_dma_check = &via82cxxx_ide_dma_check;
if (!noautodma) if (!noautodma)
hwif->autodma = 1; hwif->autodma = 1;
@ -616,24 +468,35 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->drives[1].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma;
} }
static ide_pci_device_t via82cxxx_chipset __devinitdata = { static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
.name = "VP_IDE", { /* 0 */
.init_chipset = init_chipset_via82cxxx, .name = "VP_IDE",
.init_hwif = init_hwif_via82cxxx, .init_chipset = init_chipset_via82cxxx,
.channels = 2, .init_hwif = init_hwif_via82cxxx,
.autodma = NOAUTODMA, .channels = 2,
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, .autodma = NOAUTODMA,
.bootable = ON_BOARD, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
.bootable = ON_BOARD
},{ /* 1 */
.name = "VP_IDE",
.init_chipset = init_chipset_via82cxxx,
.init_hwif = init_hwif_via82cxxx,
.channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
.bootable = ON_BOARD,
}
}; };
static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id) static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{ {
return ide_setup_pci_device(dev, &via82cxxx_chipset); return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
} }
static struct pci_device_id via_pci_tbl[] = { static struct pci_device_id via_pci_tbl[] = {
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ 0, }, { 0, },
}; };
MODULE_DEVICE_TABLE(pci, via_pci_tbl); MODULE_DEVICE_TABLE(pci, via_pci_tbl);

View File

@ -1401,20 +1401,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
/* We probe the hwif now */ /* We probe the hwif now */
probe_hwif_init(hwif); probe_hwif_init(hwif);
/* The code IDE code will have set hwif->present if we have devices attached,
* if we don't, the discard the interface except if we are on a media bay slot
*/
if (!hwif->present && !pmif->mediabay) {
printk(KERN_INFO "ide%d: Bus empty, interface released.\n",
hwif->index);
default_hwif_iops(hwif);
for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; ++i)
hwif->io_ports[i] = 0;
hwif->chipset = ide_unknown;
hwif->noprobe = 1;
return -ENODEV;
}
return 0; return 0;
} }

View File

@ -787,7 +787,7 @@ static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers); static LIST_HEAD(ide_pci_drivers);
/* /*
* __ide_register_pci_driver - attach IDE driver * __ide_pci_register_driver - attach IDE driver
* @driver: pci driver * @driver: pci driver
* @module: owner module of the driver * @module: owner module of the driver
* *

View File

@ -312,7 +312,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
int ret, length, hdr_len, copy_offset; int ret, length, hdr_len, copy_offset;
int rmpp_active = 0; int rmpp_active = 0;
if (count < sizeof (struct ib_user_mad)) if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
return -EINVAL; return -EINVAL;
length = count - sizeof (struct ib_user_mad); length = count - sizeof (struct ib_user_mad);

View File

@ -730,14 +730,15 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
} }
if (attr_mask & IB_QP_ACCESS_FLAGS) { if (attr_mask & IB_QP_ACCESS_FLAGS) {
qp_context->params2 |=
cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
MTHCA_QP_BIT_RWE : 0);
/* /*
* Only enable RDMA/atomics if we have responder * Only enable RDMA reads and atomics if we have
* resources set to a non-zero value. * responder resources set to a non-zero value.
*/ */
if (qp->resp_depth) { if (qp->resp_depth) {
qp_context->params2 |=
cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
MTHCA_QP_BIT_RWE : 0);
qp_context->params2 |= qp_context->params2 |=
cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ? cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
MTHCA_QP_BIT_RRE : 0); MTHCA_QP_BIT_RRE : 0);
@ -759,22 +760,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
if (qp->resp_depth && !attr->max_dest_rd_atomic) { if (qp->resp_depth && !attr->max_dest_rd_atomic) {
/* /*
* Lowering our responder resources to zero. * Lowering our responder resources to zero.
* Turn off RDMA/atomics as responder. * Turn off reads RDMA and atomics as responder.
* (RWE/RRE/RAE in params2 already zero) * (RRE/RAE in params2 already zero)
*/ */
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
MTHCA_QP_OPTPAR_RRE |
MTHCA_QP_OPTPAR_RAE); MTHCA_QP_OPTPAR_RAE);
} }
if (!qp->resp_depth && attr->max_dest_rd_atomic) { if (!qp->resp_depth && attr->max_dest_rd_atomic) {
/* /*
* Increasing our responder resources from * Increasing our responder resources from
* zero. Turn on RDMA/atomics as appropriate. * zero. Turn on RDMA reads and atomics as
* appropriate.
*/ */
qp_context->params2 |=
cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_WRITE ?
MTHCA_QP_BIT_RWE : 0);
qp_context->params2 |= qp_context->params2 |=
cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ? cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
MTHCA_QP_BIT_RRE : 0); MTHCA_QP_BIT_RRE : 0);
@ -782,8 +780,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ? cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
MTHCA_QP_BIT_RAE : 0); MTHCA_QP_BIT_RAE : 0);
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
MTHCA_QP_OPTPAR_RRE |
MTHCA_QP_OPTPAR_RAE); MTHCA_QP_OPTPAR_RAE);
} }
@ -921,10 +918,12 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev,
else else
qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg); qp->sq.max_gs = min_t(int, dev->limits.max_sg,
qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) - max_data_size / sizeof (struct mthca_data_seg));
sizeof (struct mthca_next_seg)) / qp->rq.max_gs = min_t(int, dev->limits.max_sg,
sizeof (struct mthca_data_seg); (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
sizeof (struct mthca_next_seg)) /
sizeof (struct mthca_data_seg));
} }
/* /*

View File

@ -802,13 +802,21 @@ static int srp_post_recv(struct srp_target_port *target)
/* /*
* Must be called with target->scsi_host->host_lock held to protect * Must be called with target->scsi_host->host_lock held to protect
* req_lim and tx_head. * req_lim and tx_head. Lock cannot be dropped between call here and
* call to __srp_post_send().
*/ */
static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target) static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
{ {
if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
return NULL; return NULL;
if (unlikely(target->req_lim < 1)) {
if (printk_ratelimit())
printk(KERN_DEBUG PFX "Target has req_lim %d\n",
target->req_lim);
return NULL;
}
return target->tx_ring[target->tx_head & SRP_SQ_SIZE]; return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
} }
@ -823,11 +831,6 @@ static int __srp_post_send(struct srp_target_port *target,
struct ib_send_wr wr, *bad_wr; struct ib_send_wr wr, *bad_wr;
int ret = 0; int ret = 0;
if (target->req_lim < 1) {
printk(KERN_ERR PFX "Target has req_lim %d\n", target->req_lim);
return -EAGAIN;
}
list.addr = iu->dma; list.addr = iu->dma;
list.length = len; list.length = len;
list.lkey = target->srp_host->mr->lkey; list.lkey = target->srp_host->mr->lkey;
@ -1417,6 +1420,8 @@ static ssize_t srp_create_target(struct class_device *class_dev,
if (!target_host) if (!target_host)
return -ENOMEM; return -ENOMEM;
target_host->max_lun = SRP_MAX_LUN;
target = host_to_target(target_host); target = host_to_target(target_host);
memset(target, 0, sizeof *target); memset(target, 0, sizeof *target);

View File

@ -54,6 +54,7 @@ enum {
SRP_PORT_REDIRECT = 1, SRP_PORT_REDIRECT = 1,
SRP_DLID_REDIRECT = 2, SRP_DLID_REDIRECT = 2,
SRP_MAX_LUN = 512,
SRP_MAX_IU_LEN = 256, SRP_MAX_IU_LEN = 256,
SRP_RQ_SHIFT = 6, SRP_RQ_SHIFT = 6,

View File

@ -339,14 +339,20 @@ static struct gameport_event *gameport_get_event(void)
return event; return event;
} }
static void gameport_handle_events(void) static void gameport_handle_event(void)
{ {
struct gameport_event *event; struct gameport_event *event;
struct gameport_driver *gameport_drv; struct gameport_driver *gameport_drv;
down(&gameport_sem); down(&gameport_sem);
while ((event = gameport_get_event())) { /*
* Note that we handle only one event here to give swsusp
* a chance to freeze kgameportd thread. Gameport events
* should be pretty rare so we are not concerned about
* taking performance hit.
*/
if ((event = gameport_get_event())) {
switch (event->type) { switch (event->type) {
case GAMEPORT_REGISTER_PORT: case GAMEPORT_REGISTER_PORT:
@ -433,7 +439,7 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
static int gameport_thread(void *nothing) static int gameport_thread(void *nothing)
{ {
do { do {
gameport_handle_events(); gameport_handle_event();
wait_event_interruptible(gameport_wait, wait_event_interruptible(gameport_wait,
kthread_should_stop() || !list_empty(&gameport_event_list)); kthread_should_stop() || !list_empty(&gameport_event_list));
try_to_freeze(); try_to_freeze();

View File

@ -536,7 +536,7 @@ static struct attribute *input_dev_attrs[] = {
NULL NULL
}; };
static struct attribute_group input_dev_group = { static struct attribute_group input_dev_attr_group = {
.attrs = input_dev_attrs, .attrs = input_dev_attrs,
}; };
@ -717,35 +717,14 @@ struct input_dev *input_allocate_device(void)
return dev; return dev;
} }
static void input_register_classdevice(struct input_dev *dev)
{
static atomic_t input_no = ATOMIC_INIT(0);
const char *path;
__module_get(THIS_MODULE);
dev->dev = dev->cdev.dev;
snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
printk(KERN_INFO "input: %s as %s/%s\n",
dev->name ? dev->name : "Unspecified device",
path ? path : "", dev->cdev.class_id);
kfree(path);
class_device_add(&dev->cdev);
sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
}
int input_register_device(struct input_dev *dev) int input_register_device(struct input_dev *dev)
{ {
static atomic_t input_no = ATOMIC_INIT(0);
struct input_handle *handle; struct input_handle *handle;
struct input_handler *handler; struct input_handler *handler;
struct input_device_id *id; struct input_device_id *id;
const char *path;
int error;
if (!dev->dynalloc) { if (!dev->dynalloc) {
printk(KERN_WARNING "input: device %s is statically allocated, will not register\n" printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
@ -773,7 +752,32 @@ int input_register_device(struct input_dev *dev)
INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->h_list);
list_add_tail(&dev->node, &input_dev_list); list_add_tail(&dev->node, &input_dev_list);
input_register_classdevice(dev); dev->cdev.class = &input_class;
snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
error = class_device_add(&dev->cdev);
if (error)
return error;
error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group);
if (error)
goto fail1;
error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
if (error)
goto fail2;
error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
if (error)
goto fail3;
__module_get(THIS_MODULE);
path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
printk(KERN_INFO "input: %s as %s\n",
dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
kfree(path);
list_for_each_entry(handler, &input_handler_list, node) list_for_each_entry(handler, &input_handler_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
@ -784,6 +788,11 @@ int input_register_device(struct input_dev *dev)
input_wakeup_procfs_readers(); input_wakeup_procfs_readers();
return 0; return 0;
fail3: sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
fail2: sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
fail1: class_device_del(&dev->cdev);
return error;
} }
void input_unregister_device(struct input_dev *dev) void input_unregister_device(struct input_dev *dev)
@ -805,7 +814,7 @@ void input_unregister_device(struct input_dev *dev)
sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
sysfs_remove_group(&dev->cdev.kobj, &input_dev_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
class_device_unregister(&dev->cdev); class_device_unregister(&dev->cdev);
input_wakeup_procfs_readers(); input_wakeup_procfs_readers();

View File

@ -166,6 +166,9 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_SPECIAL 248 #define ATKBD_SPECIAL 248
#define ATKBD_LED_EVENT_BIT 0
#define ATKBD_REP_EVENT_BIT 1
static struct { static struct {
unsigned char keycode; unsigned char keycode;
unsigned char set2; unsigned char set2;
@ -211,6 +214,10 @@ struct atkbd {
unsigned char err_xl; unsigned char err_xl;
unsigned int last; unsigned int last;
unsigned long time; unsigned long time;
struct work_struct event_work;
struct semaphore event_sem;
unsigned long event_mask;
}; };
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
@ -424,58 +431,86 @@ out:
} }
/* /*
* Event callback from the input module. Events that change the state of * atkbd_event_work() is used to complete processing of events that
* the hardware are processed here. * can not be processed by input_event() which is often called from
* interrupt context.
*/ */
static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) static void atkbd_event_work(void *data)
{ {
struct atkbd *atkbd = dev->private;
const short period[32] = const short period[32] =
{ 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125,
133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 }; 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
const short delay[4] = const short delay[4] =
{ 250, 500, 750, 1000 }; { 250, 500, 750, 1000 };
struct atkbd *atkbd = data;
struct input_dev *dev = atkbd->dev;
unsigned char param[2]; unsigned char param[2];
int i, j; int i, j;
down(&atkbd->event_sem);
if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) {
param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
| (test_bit(LED_NUML, dev->led) ? 2 : 0)
| (test_bit(LED_CAPSL, dev->led) ? 4 : 0);
ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);
if (atkbd->extra) {
param[0] = 0;
param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
| (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0)
| (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
| (test_bit(LED_MISC, dev->led) ? 0x10 : 0)
| (test_bit(LED_MUTE, dev->led) ? 0x20 : 0);
ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
}
}
if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) {
i = j = 0;
while (i < 31 && period[i] < dev->rep[REP_PERIOD])
i++;
while (j < 3 && delay[j] < dev->rep[REP_DELAY])
j++;
dev->rep[REP_PERIOD] = period[i];
dev->rep[REP_DELAY] = delay[j];
param[0] = i | (j << 5);
ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
}
up(&atkbd->event_sem);
}
/*
* Event callback from the input module. Events that change the state of
* the hardware are processed here. If action can not be performed in
* interrupt context it is offloaded to atkbd_event_work.
*/
static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct atkbd *atkbd = dev->private;
if (!atkbd->write) if (!atkbd->write)
return -1; return -1;
switch (type) { switch (type) {
case EV_LED: case EV_LED:
set_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask);
param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) wmb();
| (test_bit(LED_NUML, dev->led) ? 2 : 0) schedule_work(&atkbd->event_work);
| (test_bit(LED_CAPSL, dev->led) ? 4 : 0);
ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);
if (atkbd->extra) {
param[0] = 0;
param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
| (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0)
| (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
| (test_bit(LED_MISC, dev->led) ? 0x10 : 0)
| (test_bit(LED_MUTE, dev->led) ? 0x20 : 0);
ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
}
return 0; return 0;
case EV_REP: case EV_REP:
if (atkbd->softrepeat) return 0; if (!atkbd->softrepeat) {
set_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask);
i = j = 0; wmb();
while (i < 31 && period[i] < dev->rep[REP_PERIOD]) schedule_work(&atkbd->event_work);
i++; }
while (j < 3 && delay[j] < dev->rep[REP_DELAY])
j++;
dev->rep[REP_PERIOD] = period[i];
dev->rep[REP_DELAY] = delay[j];
param[0] = i | (j << 5);
ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
return 0; return 0;
} }
@ -810,6 +845,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd->dev = dev; atkbd->dev = dev;
ps2_init(&atkbd->ps2dev, serio); ps2_init(&atkbd->ps2dev, serio);
INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
init_MUTEX(&atkbd->event_sem);
switch (serio->id.type) { switch (serio->id.type) {

View File

@ -40,6 +40,16 @@ config INPUT_M68K_BEEP
tristate "M68k Beeper support" tristate "M68k Beeper support"
depends on M68K depends on M68K
config INPUT_WISTRON_BTNS
tristate "x86 Wistron laptop button interface"
depends on X86 && !X86_64
help
Say Y here for support of Winstron laptop button interface, used on
laptops of various brands, including Acer and Fujitsu-Siemens.
To compile this driver as a module, choose M here: the module will
be called wistron_btns.
config INPUT_UINPUT config INPUT_UINPUT
tristate "User level driver support" tristate "User level driver support"
help help

View File

@ -9,4 +9,5 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o

View File

@ -92,24 +92,19 @@ static void uinput_request_done(struct uinput_device *udev, struct uinput_reques
{ {
/* Mark slot as available */ /* Mark slot as available */
udev->requests[request->id] = NULL; udev->requests[request->id] = NULL;
wake_up_interruptible(&udev->requests_waitq); wake_up(&udev->requests_waitq);
complete(&request->done); complete(&request->done);
} }
static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request) static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
{ {
int retval;
/* Tell our userspace app about this new request by queueing an input event */ /* Tell our userspace app about this new request by queueing an input event */
uinput_dev_event(dev, EV_UINPUT, request->code, request->id); uinput_dev_event(dev, EV_UINPUT, request->code, request->id);
/* Wait for the request to complete */ /* Wait for the request to complete */
retval = wait_for_completion_interruptible(&request->done); wait_for_completion(&request->done);
if (!retval) return request->retval;
retval = request->retval;
return retval;
} }
static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect) static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
@ -152,67 +147,62 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
return retval; return retval;
} }
static void uinput_destroy_device(struct uinput_device *udev)
{
const char *name, *phys;
if (udev->dev) {
name = udev->dev->name;
phys = udev->dev->phys;
if (udev->state == UIST_CREATED)
input_unregister_device(udev->dev);
else
input_free_device(udev->dev);
kfree(name);
kfree(phys);
udev->dev = NULL;
}
udev->state = UIST_NEW_DEVICE;
}
static int uinput_create_device(struct uinput_device *udev) static int uinput_create_device(struct uinput_device *udev)
{ {
if (!udev->dev->name) { int error;
if (udev->state != UIST_SETUP_COMPLETE) {
printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME); printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
return -EINVAL; return -EINVAL;
} }
udev->dev->event = uinput_dev_event; error = input_register_device(udev->dev);
udev->dev->upload_effect = uinput_dev_upload_effect; if (error) {
udev->dev->erase_effect = uinput_dev_erase_effect; uinput_destroy_device(udev);
udev->dev->private = udev; return error;
init_waitqueue_head(&udev->waitq);
input_register_device(udev->dev);
set_bit(UIST_CREATED, &udev->state);
return 0;
}
static int uinput_destroy_device(struct uinput_device *udev)
{
if (!test_bit(UIST_CREATED, &udev->state)) {
printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
return -EINVAL;
} }
input_unregister_device(udev->dev); udev->state = UIST_CREATED;
clear_bit(UIST_CREATED, &udev->state);
return 0; return 0;
} }
static int uinput_open(struct inode *inode, struct file *file) static int uinput_open(struct inode *inode, struct file *file)
{ {
struct uinput_device *newdev; struct uinput_device *newdev;
struct input_dev *newinput;
newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL); newdev = kzalloc(sizeof(struct uinput_device), GFP_KERNEL);
if (!newdev) if (!newdev)
goto error; return -ENOMEM;
memset(newdev, 0, sizeof(struct uinput_device));
init_MUTEX(&newdev->sem);
spin_lock_init(&newdev->requests_lock); spin_lock_init(&newdev->requests_lock);
init_waitqueue_head(&newdev->requests_waitq); init_waitqueue_head(&newdev->requests_waitq);
init_waitqueue_head(&newdev->waitq);
newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL); newdev->state = UIST_NEW_DEVICE;
if (!newinput)
goto cleanup;
memset(newinput, 0, sizeof(struct input_dev));
newdev->dev = newinput;
file->private_data = newdev; file->private_data = newdev;
return 0; return 0;
cleanup:
kfree(newdev);
error:
return -ENOMEM;
} }
static int uinput_validate_absbits(struct input_dev *dev) static int uinput_validate_absbits(struct input_dev *dev)
@ -246,34 +236,55 @@ static int uinput_validate_absbits(struct input_dev *dev)
return retval; return retval;
} }
static int uinput_alloc_device(struct file *file, const char __user *buffer, size_t count) static int uinput_allocate_device(struct uinput_device *udev)
{
udev->dev = input_allocate_device();
if (!udev->dev)
return -ENOMEM;
udev->dev->event = uinput_dev_event;
udev->dev->upload_effect = uinput_dev_upload_effect;
udev->dev->erase_effect = uinput_dev_erase_effect;
udev->dev->private = udev;
return 0;
}
static int uinput_setup_device(struct uinput_device *udev, const char __user *buffer, size_t count)
{ {
struct uinput_user_dev *user_dev; struct uinput_user_dev *user_dev;
struct input_dev *dev; struct input_dev *dev;
struct uinput_device *udev;
char *name; char *name;
int size; int size;
int retval; int retval;
retval = count; if (count != sizeof(struct uinput_user_dev))
return -EINVAL;
if (!udev->dev) {
retval = uinput_allocate_device(udev);
if (retval)
return retval;
}
udev = file->private_data;
dev = udev->dev; dev = udev->dev;
user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL);
if (!user_dev) { if (!user_dev)
retval = -ENOMEM; return -ENOMEM;
goto exit;
}
if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) { if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
retval = -EFAULT; retval = -EFAULT;
goto exit; goto exit;
} }
kfree(dev->name);
size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
if (!size) {
retval = -EINVAL;
goto exit;
}
kfree(dev->name);
dev->name = name = kmalloc(size, GFP_KERNEL); dev->name = name = kmalloc(size, GFP_KERNEL);
if (!name) { if (!name) {
retval = -ENOMEM; retval = -ENOMEM;
@ -296,32 +307,50 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz
/* check if absmin/absmax/absfuzz/absflat are filled as /* check if absmin/absmax/absfuzz/absflat are filled as
* told in Documentation/input/input-programming.txt */ * told in Documentation/input/input-programming.txt */
if (test_bit(EV_ABS, dev->evbit)) { if (test_bit(EV_ABS, dev->evbit)) {
int err = uinput_validate_absbits(dev); retval = uinput_validate_absbits(dev);
if (err < 0) { if (retval < 0)
retval = err; goto exit;
kfree(dev->name);
}
} }
exit: udev->state = UIST_SETUP_COMPLETE;
retval = count;
exit:
kfree(user_dev); kfree(user_dev);
return retval; return retval;
} }
static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char __user *buffer, size_t count)
{
struct input_event ev;
if (count != sizeof(struct input_event))
return -EINVAL;
if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
return -EFAULT;
input_event(udev->dev, ev.type, ev.code, ev.value);
return sizeof(struct input_event);
}
static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{ {
struct uinput_device *udev = file->private_data; struct uinput_device *udev = file->private_data;
int retval;
if (test_bit(UIST_CREATED, &udev->state)) { retval = down_interruptible(&udev->sem);
struct input_event ev; if (retval)
return retval;
if (copy_from_user(&ev, buffer, sizeof(struct input_event))) retval = udev->state == UIST_CREATED ?
return -EFAULT; uinput_inject_event(udev, buffer, count) :
input_event(udev->dev, ev.type, ev.code, ev.value); uinput_setup_device(udev, buffer, count);
} else
count = uinput_alloc_device(file, buffer, count);
return count; up(&udev->sem);
return retval;
} }
static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
@ -329,28 +358,38 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count,
struct uinput_device *udev = file->private_data; struct uinput_device *udev = file->private_data;
int retval = 0; int retval = 0;
if (!test_bit(UIST_CREATED, &udev->state)) if (udev->state != UIST_CREATED)
return -ENODEV; return -ENODEV;
if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK)) if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
return -EAGAIN; return -EAGAIN;
retval = wait_event_interruptible(udev->waitq, retval = wait_event_interruptible(udev->waitq,
udev->head != udev->tail || !test_bit(UIST_CREATED, &udev->state)); udev->head != udev->tail || udev->state != UIST_CREATED);
if (retval) if (retval)
return retval; return retval;
if (!test_bit(UIST_CREATED, &udev->state)) retval = down_interruptible(&udev->sem);
return -ENODEV; if (retval)
return retval;
while ((udev->head != udev->tail) && if (udev->state != UIST_CREATED) {
(retval + sizeof(struct input_event) <= count)) { retval = -ENODEV;
if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) goto out;
return -EFAULT; }
while (udev->head != udev->tail && retval + sizeof(struct input_event) <= count) {
if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) {
retval = -EFAULT;
goto out;
}
udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
retval += sizeof(struct input_event); retval += sizeof(struct input_event);
} }
out:
up(&udev->sem);
return retval; return retval;
} }
@ -366,28 +405,30 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait)
return 0; return 0;
} }
static int uinput_burn_device(struct uinput_device *udev) static int uinput_release(struct inode *inode, struct file *file)
{ {
if (test_bit(UIST_CREATED, &udev->state)) struct uinput_device *udev = file->private_data;
uinput_destroy_device(udev);
kfree(udev->dev->name); uinput_destroy_device(udev);
kfree(udev->dev->phys);
kfree(udev->dev);
kfree(udev); kfree(udev);
return 0; return 0;
} }
static int uinput_close(struct inode *inode, struct file *file) #define uinput_set_bit(_arg, _bit, _max) \
{ ({ \
uinput_burn_device(file->private_data); int __ret = 0; \
return 0; if (udev->state == UIST_CREATED) \
} __ret = -EINVAL; \
else if ((_arg) > (_max)) \
__ret = -EINVAL; \
else set_bit((_arg), udev->dev->_bit); \
__ret; \
})
static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
int retval = 0; int retval;
struct uinput_device *udev; struct uinput_device *udev;
void __user *p = (void __user *)arg; void __user *p = (void __user *)arg;
struct uinput_ff_upload ff_up; struct uinput_ff_upload ff_up;
@ -398,19 +439,14 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
udev = file->private_data; udev = file->private_data;
/* device attributes can not be changed after the device is created */ retval = down_interruptible(&udev->sem);
switch (cmd) { if (retval)
case UI_SET_EVBIT: return retval;
case UI_SET_KEYBIT:
case UI_SET_RELBIT: if (!udev->dev) {
case UI_SET_ABSBIT: retval = uinput_allocate_device(udev);
case UI_SET_MSCBIT: if (retval)
case UI_SET_LEDBIT: goto out;
case UI_SET_SNDBIT:
case UI_SET_FFBIT:
case UI_SET_PHYS:
if (test_bit(UIST_CREATED, &udev->state))
return -EINVAL;
} }
switch (cmd) { switch (cmd) {
@ -419,74 +455,50 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
break; break;
case UI_DEV_DESTROY: case UI_DEV_DESTROY:
retval = uinput_destroy_device(udev); uinput_destroy_device(udev);
break; break;
case UI_SET_EVBIT: case UI_SET_EVBIT:
if (arg > EV_MAX) { retval = uinput_set_bit(arg, evbit, EV_MAX);
retval = -EINVAL;
break;
}
set_bit(arg, udev->dev->evbit);
break; break;
case UI_SET_KEYBIT: case UI_SET_KEYBIT:
if (arg > KEY_MAX) { retval = uinput_set_bit(arg, keybit, KEY_MAX);
retval = -EINVAL;
break;
}
set_bit(arg, udev->dev->keybit);
break; break;
case UI_SET_RELBIT: case UI_SET_RELBIT:
if (arg > REL_MAX) { retval = uinput_set_bit(arg, relbit, REL_MAX);
retval = -EINVAL;
break;
}
set_bit(arg, udev->dev->relbit);
break; break;
case UI_SET_ABSBIT: case UI_SET_ABSBIT:
if (arg > ABS_MAX) { retval = uinput_set_bit(arg, absbit, ABS_MAX);
retval = -EINVAL;
break;
}
set_bit(arg, udev->dev->absbit);
break; break;
case UI_SET_MSCBIT: case UI_SET_MSCBIT:
if (arg > MSC_MAX) { retval = uinput_set_bit(arg, mscbit, MSC_MAX);
retval = -EINVAL;
break;
}
set_bit(arg, udev->dev->mscbit);
break; break;
case UI_SET_LEDBIT: case UI_SET_LEDBIT:
if (arg > LED_MAX) { retval = uinput_set_bit(arg, ledbit, LED_MAX);
retval = -EINVAL;
break;
}
set_bit(arg, udev->dev->ledbit);
break; break;
case UI_SET_SNDBIT: case UI_SET_SNDBIT:
if (arg > SND_MAX) { retval = uinput_set_bit(arg, sndbit, SND_MAX);
retval = -EINVAL;
break;
}
set_bit(arg, udev->dev->sndbit);
break; break;
case UI_SET_FFBIT: case UI_SET_FFBIT:
if (arg > FF_MAX) { retval = uinput_set_bit(arg, ffbit, FF_MAX);
retval = -EINVAL; break;
break;
} case UI_SET_SWBIT:
set_bit(arg, udev->dev->ffbit); retval = uinput_set_bit(arg, swbit, SW_MAX);
break; break;
case UI_SET_PHYS: case UI_SET_PHYS:
if (udev->state == UIST_CREATED) {
retval = -EINVAL;
goto out;
}
length = strnlen_user(p, 1024); length = strnlen_user(p, 1024);
if (length <= 0) { if (length <= 0) {
retval = -EFAULT; retval = -EFAULT;
@ -575,23 +587,26 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
default: default:
retval = -EINVAL; retval = -EINVAL;
} }
out:
up(&udev->sem);
return retval; return retval;
} }
static struct file_operations uinput_fops = { static struct file_operations uinput_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = uinput_open, .open = uinput_open,
.release = uinput_close, .release = uinput_release,
.read = uinput_read, .read = uinput_read,
.write = uinput_write, .write = uinput_write,
.poll = uinput_poll, .poll = uinput_poll,
.ioctl = uinput_ioctl, .unlocked_ioctl = uinput_ioctl,
}; };
static struct miscdevice uinput_misc = { static struct miscdevice uinput_misc = {
.fops = &uinput_fops, .fops = &uinput_fops,
.minor = UINPUT_MINOR, .minor = UINPUT_MINOR,
.name = UINPUT_NAME, .name = UINPUT_NAME,
}; };
static int __init uinput_init(void) static int __init uinput_init(void)

View File

@ -0,0 +1,561 @@
/*
* Wistron laptop button driver
* Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
* Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
* Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
*
* You can redistribute and/or modify this program under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
*/
#include <asm/io.h>
#include <linux/dmi.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mc146818rtc.h>
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/platform_device.h>
/*
* Number of attempts to read data from queue per poll;
* the queue can hold up to 31 entries
*/
#define MAX_POLL_ITERATIONS 64
#define POLL_FREQUENCY 10 /* Number of polls per second */
#if POLL_FREQUENCY > HZ
#error "POLL_FREQUENCY too high"
#endif
/* BIOS subsystem IDs */
#define WIFI 0x35
#define BLUETOOTH 0x34
MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
MODULE_DESCRIPTION("Wistron laptop button driver");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.1");
static int force; /* = 0; */
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Load even if computer is not in database");
static char *keymap_name; /* = NULL; */
module_param_named(keymap, keymap_name, charp, 0);
MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected");
static struct platform_device *wistron_device;
/* BIOS interface implementation */
static void __iomem *bios_entry_point; /* BIOS routine entry point */
static void __iomem *bios_code_map_base;
static void __iomem *bios_data_map_base;
static u8 cmos_address;
struct regs {
u32 eax, ebx, ecx;
};
static void call_bios(struct regs *regs)
{
unsigned long flags;
preempt_disable();
local_irq_save(flags);
asm volatile ("pushl %%ebp;"
"movl %7, %%ebp;"
"call *%6;"
"popl %%ebp"
: "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx)
: "0" (regs->eax), "1" (regs->ebx), "2" (regs->ecx),
"m" (bios_entry_point), "m" (bios_data_map_base)
: "edx", "edi", "esi", "memory");
local_irq_restore(flags);
preempt_enable();
}
static size_t __init locate_wistron_bios(void __iomem *base)
{
static const unsigned char __initdata signature[] =
{ 0x42, 0x21, 0x55, 0x30 };
size_t offset;
for (offset = 0; offset < 0x10000; offset += 0x10) {
if (check_signature(base + offset, signature,
sizeof(signature)) != 0)
return offset;
}
return -1;
}
static int __init map_bios(void)
{
void __iomem *base;
size_t offset;
u32 entry_point;
base = ioremap(0xF0000, 0x10000); /* Can't fail */
offset = locate_wistron_bios(base);
if (offset < 0) {
printk(KERN_ERR "wistron_btns: BIOS entry point not found\n");
iounmap(base);
return -ENODEV;
}
entry_point = readl(base + offset + 5);
printk(KERN_DEBUG
"wistron_btns: BIOS signature found at %p, entry point %08X\n",
base + offset, entry_point);
if (entry_point >= 0xF0000) {
bios_code_map_base = base;
bios_entry_point = bios_code_map_base + (entry_point & 0xFFFF);
} else {
iounmap(base);
bios_code_map_base = ioremap(entry_point & ~0x3FFF, 0x4000);
if (bios_code_map_base == NULL) {
printk(KERN_ERR
"wistron_btns: Can't map BIOS code at %08X\n",
entry_point & ~0x3FFF);
goto err;
}
bios_entry_point = bios_code_map_base + (entry_point & 0x3FFF);
}
/* The Windows driver maps 0x10000 bytes, we keep only one page... */
bios_data_map_base = ioremap(0x400, 0xc00);
if (bios_data_map_base == NULL) {
printk(KERN_ERR "wistron_btns: Can't map BIOS data\n");
goto err_code;
}
return 0;
err_code:
iounmap(bios_code_map_base);
err:
return -ENOMEM;
}
static inline void unmap_bios(void)
{
iounmap(bios_code_map_base);
iounmap(bios_data_map_base);
}
/* BIOS calls */
static u16 bios_pop_queue(void)
{
struct regs regs;
memset(&regs, 0, sizeof (regs));
regs.eax = 0x9610;
regs.ebx = 0x061C;
regs.ecx = 0x0000;
call_bios(&regs);
return regs.eax;
}
static void __init bios_attach(void)
{
struct regs regs;
memset(&regs, 0, sizeof (regs));
regs.eax = 0x9610;
regs.ebx = 0x012E;
call_bios(&regs);
}
static void bios_detach(void)
{
struct regs regs;
memset(&regs, 0, sizeof (regs));
regs.eax = 0x9610;
regs.ebx = 0x002E;
call_bios(&regs);
}
static u8 __init bios_get_cmos_address(void)
{
struct regs regs;
memset(&regs, 0, sizeof (regs));
regs.eax = 0x9610;
regs.ebx = 0x051C;
call_bios(&regs);
return regs.ecx;
}
static u16 __init bios_get_default_setting(u8 subsys)
{
struct regs regs;
memset(&regs, 0, sizeof (regs));
regs.eax = 0x9610;
regs.ebx = 0x0200 | subsys;
call_bios(&regs);
return regs.eax;
}
static void bios_set_state(u8 subsys, int enable)
{
struct regs regs;
memset(&regs, 0, sizeof (regs));
regs.eax = 0x9610;
regs.ebx = (enable ? 0x0100 : 0x0000) | subsys;
call_bios(&regs);
}
/* Hardware database */
struct key_entry {
char type; /* See KE_* below */
u8 code;
unsigned keycode; /* For KE_KEY */
};
enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH };
static const struct key_entry *keymap; /* = NULL; Current key map */
static int have_wifi;
static int have_bluetooth;
static int __init dmi_matched(struct dmi_system_id *dmi)
{
const struct key_entry *key;
keymap = dmi->driver_data;
for (key = keymap; key->type != KE_END; key++) {
if (key->type == KE_WIFI) {
have_wifi = 1;
break;
} else if (key->type == KE_BLUETOOTH) {
have_bluetooth = 1;
break;
}
}
return 1;
}
static struct key_entry keymap_empty[] = {
{ KE_END, 0 }
};
static struct key_entry keymap_fs_amilo_pro_v2000[] = {
{ KE_KEY, 0x01, KEY_HELP },
{ KE_KEY, 0x11, KEY_PROG1 },
{ KE_KEY, 0x12, KEY_PROG2 },
{ KE_WIFI, 0x30, 0 },
{ KE_KEY, 0x31, KEY_MAIL },
{ KE_KEY, 0x36, KEY_WWW },
{ KE_END, 0 }
};
static struct key_entry keymap_wistron_ms2141[] = {
{ KE_KEY, 0x11, KEY_PROG1 },
{ KE_KEY, 0x12, KEY_PROG2 },
{ KE_WIFI, 0x30, 0 },
{ KE_KEY, 0x22, KEY_REWIND },
{ KE_KEY, 0x23, KEY_FORWARD },
{ KE_KEY, 0x24, KEY_PLAYPAUSE },
{ KE_KEY, 0x25, KEY_STOPCD },
{ KE_KEY, 0x31, KEY_MAIL },
{ KE_KEY, 0x36, KEY_WWW },
{ KE_END, 0 }
};
static struct key_entry keymap_acer_aspire_1500[] = {
{ KE_KEY, 0x11, KEY_PROG1 },
{ KE_KEY, 0x12, KEY_PROG2 },
{ KE_WIFI, 0x30, 0 },
{ KE_KEY, 0x31, KEY_MAIL },
{ KE_KEY, 0x36, KEY_WWW },
{ KE_BLUETOOTH, 0x44, 0 },
{ KE_END, 0 }
};
/*
* If your machine is not here (which is currently rather likely), please send
* a list of buttons and their key codes (reported when loading this module
* with force=1) and the output of dmidecode to $MODULE_AUTHOR.
*/
static struct dmi_system_id dmi_ids[] = {
{
.callback = dmi_matched,
.ident = "Fujitsu-Siemens Amilo Pro V2000",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
},
.driver_data = keymap_fs_amilo_pro_v2000
},
{
.callback = dmi_matched,
.ident = "Acer Aspire 1500",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
},
.driver_data = keymap_acer_aspire_1500
},
{ 0, }
};
static int __init select_keymap(void)
{
if (keymap_name != NULL) {
if (strcmp (keymap_name, "1557/MS2141") == 0)
keymap = keymap_wistron_ms2141;
else {
printk(KERN_ERR "wistron_btns: Keymap unknown\n");
return -EINVAL;
}
}
dmi_check_system(dmi_ids);
if (keymap == NULL) {
if (!force) {
printk(KERN_ERR "wistron_btns: System unknown\n");
return -ENODEV;
}
keymap = keymap_empty;
}
return 0;
}
/* Input layer interface */
static struct input_dev *input_dev;
static int __init setup_input_dev(void)
{
const struct key_entry *key;
int error;
input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
input_dev->name = "Wistron laptop buttons";
input_dev->phys = "wistron/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->cdev.dev = &wistron_device->dev;
for (key = keymap; key->type != KE_END; key++) {
if (key->type == KE_KEY) {
input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
set_bit(key->keycode, input_dev->keybit);
}
}
error = input_register_device(input_dev);
if (error) {
input_free_device(input_dev);
return error;
}
return 0;
}
static void report_key(unsigned keycode)
{
input_report_key(input_dev, keycode, 1);
input_sync(input_dev);
input_report_key(input_dev, keycode, 0);
input_sync(input_dev);
}
/* Driver core */
static int wifi_enabled;
static int bluetooth_enabled;
static void poll_bios(unsigned long);
static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0);
static void handle_key(u8 code)
{
const struct key_entry *key;
for (key = keymap; key->type != KE_END; key++) {
if (code == key->code) {
switch (key->type) {
case KE_KEY:
report_key(key->keycode);
break;
case KE_WIFI:
if (have_wifi) {
wifi_enabled = !wifi_enabled;
bios_set_state(WIFI, wifi_enabled);
}
break;
case KE_BLUETOOTH:
if (have_bluetooth) {
bluetooth_enabled = !bluetooth_enabled;
bios_set_state(BLUETOOTH, bluetooth_enabled);
}
break;
case KE_END:
default:
BUG();
}
return;
}
}
printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
}
static void poll_bios(unsigned long discard)
{
u8 qlen;
u16 val;
for (;;) {
qlen = CMOS_READ(cmos_address);
if (qlen == 0)
break;
val = bios_pop_queue();
if (val != 0 && !discard)
handle_key((u8)val);
}
mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
}
static int wistron_suspend(struct platform_device *dev, pm_message_t state)
{
del_timer_sync(&poll_timer);
if (have_wifi)
bios_set_state(WIFI, 0);
if (have_bluetooth)
bios_set_state(BLUETOOTH, 0);
return 0;
}
static int wistron_resume(struct platform_device *dev)
{
if (have_wifi)
bios_set_state(WIFI, wifi_enabled);
if (have_bluetooth)
bios_set_state(BLUETOOTH, bluetooth_enabled);
poll_bios(1);
return 0;
}
static struct platform_driver wistron_driver = {
.suspend = wistron_suspend,
.resume = wistron_resume,
.driver = {
.name = "wistron-bios",
},
};
static int __init wb_module_init(void)
{
int err;
err = select_keymap();
if (err)
return err;
err = map_bios();
if (err)
return err;
bios_attach();
cmos_address = bios_get_cmos_address();
err = platform_driver_register(&wistron_driver);
if (err)
goto err_detach_bios;
wistron_device = platform_device_register_simple("wistron-bios", -1, NULL, 0);
if (IS_ERR(wistron_device)) {
err = PTR_ERR(wistron_device);
goto err_unregister_driver;
}
if (have_wifi) {
u16 wifi = bios_get_default_setting(WIFI);
if (wifi & 1)
wifi_enabled = (wifi & 2) ? 1 : 0;
else
have_wifi = 0;
if (have_wifi)
bios_set_state(WIFI, wifi_enabled);
}
if (have_bluetooth) {
u16 bt = bios_get_default_setting(BLUETOOTH);
if (bt & 1)
bluetooth_enabled = (bt & 2) ? 1 : 0;
else
have_bluetooth = 0;
if (have_bluetooth)
bios_set_state(BLUETOOTH, bluetooth_enabled);
}
err = setup_input_dev();
if (err)
goto err_unregister_device;
poll_bios(1); /* Flush stale event queue and arm timer */
return 0;
err_unregister_device:
platform_device_unregister(wistron_device);
err_unregister_driver:
platform_driver_unregister(&wistron_driver);
err_detach_bios:
bios_detach();
unmap_bios();
return err;
}
static void __exit wb_module_exit(void)
{
del_timer_sync(&poll_timer);
input_unregister_device(input_dev);
platform_device_unregister(wistron_device);
platform_driver_unregister(&wistron_driver);
bios_detach();
unmap_bios();
}
module_init(wb_module_init);
module_exit(wb_module_exit);

View File

@ -269,14 +269,20 @@ static struct serio_event *serio_get_event(void)
return event; return event;
} }
static void serio_handle_events(void) static void serio_handle_event(void)
{ {
struct serio_event *event; struct serio_event *event;
struct serio_driver *serio_drv; struct serio_driver *serio_drv;
down(&serio_sem); down(&serio_sem);
while ((event = serio_get_event())) { /*
* Note that we handle only one event here to give swsusp
* a chance to freeze kseriod thread. Serio events should
* be pretty rare so we are not concerned about taking
* performance hit.
*/
if ((event = serio_get_event())) {
switch (event->type) { switch (event->type) {
case SERIO_REGISTER_PORT: case SERIO_REGISTER_PORT:
@ -368,7 +374,7 @@ static struct serio *serio_get_pending_child(struct serio *parent)
static int serio_thread(void *nothing) static int serio_thread(void *nothing)
{ {
do { do {
serio_handle_events(); serio_handle_event();
wait_event_interruptible(serio_wait, wait_event_interruptible(serio_wait,
kthread_should_stop() || !list_empty(&serio_event_list)); kthread_should_stop() || !list_empty(&serio_event_list));
try_to_freeze(); try_to_freeze();

View File

@ -110,7 +110,7 @@ config HISAX_16_3
config HISAX_TELESPCI config HISAX_TELESPCI
bool "Teles PCI" bool "Teles PCI"
depends on PCI && (BROKEN || !(SPARC64 || PPC)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help help
This enables HiSax support for the Teles PCI. This enables HiSax support for the Teles PCI.
See <file:Documentation/isdn/README.HiSax> on how to configure it. See <file:Documentation/isdn/README.HiSax> on how to configure it.
@ -238,7 +238,7 @@ config HISAX_MIC
config HISAX_NETJET config HISAX_NETJET
bool "NETjet card" bool "NETjet card"
depends on PCI && (BROKEN || !(SPARC64 || PPC)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help help
This enables HiSax support for the NetJet from Traverse This enables HiSax support for the NetJet from Traverse
Technologies. Technologies.
@ -249,7 +249,7 @@ config HISAX_NETJET
config HISAX_NETJET_U config HISAX_NETJET_U
bool "NETspider U card" bool "NETspider U card"
depends on PCI && (BROKEN || !(SPARC64 || PPC)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help help
This enables HiSax support for the Netspider U interface ISDN card This enables HiSax support for the Netspider U interface ISDN card
from Traverse Technologies. from Traverse Technologies.
@ -317,7 +317,7 @@ config HISAX_GAZEL
config HISAX_HFC_PCI config HISAX_HFC_PCI
bool "HFC PCI-Bus cards" bool "HFC PCI-Bus cards"
depends on PCI && (BROKEN || !(SPARC64 || PPC)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help help
This enables HiSax support for the HFC-S PCI 2BDS0 based cards. This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
@ -344,14 +344,14 @@ config HISAX_HFC_SX
config HISAX_ENTERNOW_PCI config HISAX_ENTERNOW_PCI
bool "Formula-n enter:now PCI card" bool "Formula-n enter:now PCI card"
depends on PCI && (BROKEN || !(SPARC64 || PPC)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help help
This enables HiSax support for the Formula-n enter:now PCI This enables HiSax support for the Formula-n enter:now PCI
ISDN card. ISDN card.
config HISAX_AMD7930 config HISAX_AMD7930
bool "Am7930 (EXPERIMENTAL)" bool "Am7930 (EXPERIMENTAL)"
depends on EXPERIMENTAL && (SPARC32 || SPARC64) depends on EXPERIMENTAL && SPARC
help help
This enables HiSax support for the AMD7930 chips on some SPARCs. This enables HiSax support for the AMD7930 chips on some SPARCs.
This code is not finished yet. This code is not finished yet.

View File

@ -3,7 +3,7 @@
# #
config ISDN_DRV_PCBIT config ISDN_DRV_PCBIT
tristate "PCBIT-D support" tristate "PCBIT-D support"
depends on ISDN_I4L && ISA && (BROKEN || !PPC) depends on ISDN_I4L && ISA && (BROKEN || X86)
help help
This enables support for the PCBIT ISDN-card. This card is This enables support for the PCBIT ISDN-card. This card is
manufactured in Portugal by Octal. For running this card, manufactured in Portugal by Octal. For running this card,

View File

@ -772,7 +772,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
input_dev->name = DRIVER_NAME " remote control"; input_dev->name = DRIVER_NAME " remote control";
input_dev->phys = cinergyt2->phys; input_dev->phys = cinergyt2->phys;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
for (i = 0; ARRAY_SIZE(rc_keys); i += 3) for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3)
set_bit(rc_keys[i + 2], input_dev->keybit); set_bit(rc_keys[i + 2], input_dev->keybit);
input_dev->keycodesize = 0; input_dev->keycodesize = 0;
input_dev->keycodemax = 0; input_dev->keycodemax = 0;

View File

@ -673,7 +673,6 @@ static int ir_probe(struct device *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(sub->core->pci)); pci_name(sub->core->pci));
ir->sub = sub;
ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
input_dev->name = ir->name; input_dev->name = ir->name;
input_dev->phys = ir->phys; input_dev->phys = ir->phys;
@ -688,6 +687,9 @@ static int ir_probe(struct device *dev)
} }
input_dev->cdev.dev = &sub->core->pci->dev; input_dev->cdev.dev = &sub->core->pci->dev;
ir->input = input_dev;
ir->sub = sub;
if (ir->polling) { if (ir->polling) {
INIT_WORK(&ir->work, ir_work, ir); INIT_WORK(&ir->work, ir_work, ir);
init_timer(&ir->timer); init_timer(&ir->timer);
@ -708,7 +710,6 @@ static int ir_probe(struct device *dev)
/* all done */ /* all done */
dev_set_drvdata(dev, ir); dev_set_drvdata(dev, ir);
input_register_device(ir->input); input_register_device(ir->input);
printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
/* the remote isn't as bouncy as a keyboard */ /* the remote isn't as bouncy as a keyboard */
ir->input->rep[REP_DELAY] = repeat_delay; ir->input->rep[REP_DELAY] = repeat_delay;

View File

@ -713,6 +713,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
return -ENOMEM; return -ENOMEM;
} }
ir->dev = input_dev;
/* init hardware-specific stuff */ /* init hardware-specific stuff */
ir->mask_keycode = mask_keycode; ir->mask_keycode = mask_keycode;
ir->mask_keydown = mask_keydown; ir->mask_keydown = mask_keydown;

View File

@ -246,7 +246,7 @@ int __init ipaq_mtd_init(void)
ipaq_map[i].size = h3xxx_max_flash_size; ipaq_map[i].size = h3xxx_max_flash_size;
ipaq_map[i].set_vpp = h3xxx_set_vpp; ipaq_map[i].set_vpp = h3xxx_set_vpp;
ipaq_map[i].phys = cs_phys[i]; ipaq_map[i].phys = cs_phys[i];
ipaq_map[i].virt = __ioremap(cs_phys[i], 0x04000000, 0, 1); ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000);
if (machine_is_h3100 () || machine_is_h1900()) if (machine_is_h3100 () || machine_is_h1900())
ipaq_map[i].bankwidth = 2; ipaq_map[i].bankwidth = 2;
} }
@ -280,7 +280,7 @@ int __init ipaq_mtd_init(void)
nb_parts = ARRAY_SIZE(jornada_partitions); nb_parts = ARRAY_SIZE(jornada_partitions);
ipaq_map[0].size = jornada_max_flash_size; ipaq_map[0].size = jornada_max_flash_size;
ipaq_map[0].set_vpp = jornada56x_set_vpp; ipaq_map[0].set_vpp = jornada56x_set_vpp;
ipaq_map[0].virt = (__u32)__ioremap(0x0, 0x04000000, 0, 1); ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000);
} }
#endif #endif
#ifdef CONFIG_SA1100_JORNADA720 #ifdef CONFIG_SA1100_JORNADA720
@ -442,7 +442,7 @@ static int __init h1900_special_case(void)
ipaq_map[0].size = 0x80000; ipaq_map[0].size = 0x80000;
ipaq_map[0].set_vpp = h3xxx_set_vpp; ipaq_map[0].set_vpp = h3xxx_set_vpp;
ipaq_map[0].phys = 0x0; ipaq_map[0].phys = 0x0;
ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1); ipaq_map[0].virt = ioremap(0x0, 0x04000000);
ipaq_map[0].bankwidth = 2; ipaq_map[0].bankwidth = 2;
printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);

View File

@ -159,12 +159,12 @@ static int ixp2000_flash_probe(struct platform_device *dev)
return -ENODEV; return -ENODEV;
window_size = dev->resource->end - dev->resource->start + 1; window_size = dev->resource->end - dev->resource->start + 1;
dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n", dev_info(&dev->dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
ixp_data->nr_banks, ((u32)window_size >> 20)); ixp_data->nr_banks, ((u32)window_size >> 20));
if (plat->width != 1) { if (plat->width != 1) {
dev_err(_dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n", dev_err(&dev->dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
plat->width * 8); plat->width * 8);
return -EIO; return -EIO;
} }
@ -202,7 +202,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
dev->resource->end - dev->resource->start + 1, dev->resource->end - dev->resource->start + 1,
dev->dev.bus_id); dev->dev.bus_id);
if (!info->res) { if (!info->res) {
dev_err(_dev, "Could not reserve memory region\n"); dev_err(&dev->dev, "Could not reserve memory region\n");
err = -ENOMEM; err = -ENOMEM;
goto Error; goto Error;
} }
@ -210,7 +210,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start, info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
dev->resource->end - dev->resource->start + 1); dev->resource->end - dev->resource->start + 1);
if (!info->map.map_priv_1) { if (!info->map.map_priv_1) {
dev_err(_dev, "Failed to ioremap flash region\n"); dev_err(&dev->dev, "Failed to ioremap flash region\n");
err = -EIO; err = -EIO;
goto Error; goto Error;
} }
@ -221,13 +221,13 @@ static int ixp2000_flash_probe(struct platform_device *dev)
*/ */
erratum44_workaround = ixp2000_has_broken_slowport(); erratum44_workaround = ixp2000_has_broken_slowport();
dev_info(_dev, "Erratum 44 workaround %s\n", dev_info(&dev->dev, "Erratum 44 workaround %s\n",
erratum44_workaround ? "enabled" : "disabled"); erratum44_workaround ? "enabled" : "disabled");
#endif #endif
info->mtd = do_map_probe(plat->map_name, &info->map); info->mtd = do_map_probe(plat->map_name, &info->map);
if (!info->mtd) { if (!info->mtd) {
dev_err(_dev, "map_probe failed\n"); dev_err(&dev->dev, "map_probe failed\n");
err = -ENXIO; err = -ENXIO;
goto Error; goto Error;
} }
@ -237,7 +237,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
if (err > 0) { if (err > 0) {
err = add_mtd_partitions(info->mtd, info->partitions, err); err = add_mtd_partitions(info->mtd, info->partitions, err);
if(err) if(err)
dev_err(_dev, "Could not parse partitions\n"); dev_err(&dev->dev, "Could not parse partitions\n");
} }
if (err) if (err)
@ -251,8 +251,8 @@ Error:
} }
static struct platform_driver ixp2000_flash_driver = { static struct platform_driver ixp2000_flash_driver = {
.probe = &ixp2000_flash_probe, .probe = ixp2000_flash_probe,
.remove = &ixp2000_flash_remove .remove = ixp2000_flash_remove,
.driver = { .driver = {
.name = "IXP2000-Flash", .name = "IXP2000-Flash",
}, },

View File

@ -112,7 +112,7 @@ static int __init h1910_init (void)
if (!machine_is_h1900()) if (!machine_is_h1900())
return -ENODEV; return -ENODEV;
nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); nandaddr = ioremap(0x08000000, 0x1000);
if (!nandaddr) { if (!nandaddr) {
printk("Failed to ioremap nand flash.\n"); printk("Failed to ioremap nand flash.\n");
return -ENOMEM; return -ENOMEM;

View File

@ -32,6 +32,7 @@
* *
*/ */
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>

View File

@ -156,7 +156,7 @@
#define DRV_NAME "e100" #define DRV_NAME "e100"
#define DRV_EXT "-NAPI" #define DRV_EXT "-NAPI"
#define DRV_VERSION "3.4.14-k2"DRV_EXT #define DRV_VERSION "3.4.14-k4"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation" #define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
static void e100_get_defaults(struct nic *nic) static void e100_get_defaults(struct nic *nic)
{ {
struct param_range rfds = { .min = 16, .max = 256, .count = 64 }; struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
struct param_range cbs = { .min = 64, .max = 256, .count = 64 }; struct param_range cbs = { .min = 64, .max = 256, .count = 128 };
pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id); pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */ /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@ -1007,25 +1007,264 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
} }
/********************************************************/
/* Micro code for 8086:1229 Rev 8 */
/********************************************************/
/* Parameter values for the D101M B-step */
#define D101M_CPUSAVER_TIMER_DWORD 78
#define D101M_CPUSAVER_BUNDLE_DWORD 65
#define D101M_CPUSAVER_MIN_SIZE_DWORD 126
#define D101M_B_RCVBUNDLE_UCODE \
{\
0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
0x00380438, 0x00000000, 0x00140000, 0x00380555, \
0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
0x00380559, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
}
/********************************************************/
/* Micro code for 8086:1229 Rev 9 */
/********************************************************/
/* Parameter values for the D101S */
#define D101S_CPUSAVER_TIMER_DWORD 78
#define D101S_CPUSAVER_BUNDLE_DWORD 67
#define D101S_CPUSAVER_MIN_SIZE_DWORD 128
#define D101S_RCVBUNDLE_UCODE \
{\
0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
0x00101313, 0x00380700, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00130831, \
0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
0x00041000, 0x00010004, 0x00380700 \
}
/********************************************************/
/* Micro code for the 8086:1229 Rev F/10 */
/********************************************************/
/* Parameter values for the D102 E-step */
#define D102_E_CPUSAVER_TIMER_DWORD 42
#define D102_E_CPUSAVER_BUNDLE_DWORD 54
#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46
#define D102_E_RCVBUNDLE_UCODE \
{\
0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
}
static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
{ {
int i; /* *INDENT-OFF* */
static const u32 ucode[UCODE_SIZE] = { static struct {
/* NFS packets are misinterpreted as TCO packets and u32 ucode[UCODE_SIZE + 1];
* incorrectly routed to the BMC over SMBus. This u8 mac;
* microcode patch checks the fragmented IP bit in the u8 timer_dword;
* NFS/UDP header to distinguish between NFS and TCO. */ u8 bundle_dword;
0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, u8 min_size_dword;
0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, } ucode_opts[] = {
0x00906EFD, 0x00900EFD, 0x00E00EF8, { D101M_B_RCVBUNDLE_UCODE,
}; mac_82559_D101M,
D101M_CPUSAVER_TIMER_DWORD,
D101M_CPUSAVER_BUNDLE_DWORD,
D101M_CPUSAVER_MIN_SIZE_DWORD },
{ D101S_RCVBUNDLE_UCODE,
mac_82559_D101S,
D101S_CPUSAVER_TIMER_DWORD,
D101S_CPUSAVER_BUNDLE_DWORD,
D101S_CPUSAVER_MIN_SIZE_DWORD },
{ D102_E_RCVBUNDLE_UCODE,
mac_82551_F,
D102_E_CPUSAVER_TIMER_DWORD,
D102_E_CPUSAVER_BUNDLE_DWORD,
D102_E_CPUSAVER_MIN_SIZE_DWORD },
{ D102_E_RCVBUNDLE_UCODE,
mac_82551_10,
D102_E_CPUSAVER_TIMER_DWORD,
D102_E_CPUSAVER_BUNDLE_DWORD,
D102_E_CPUSAVER_MIN_SIZE_DWORD },
{ {0}, 0, 0, 0, 0}
}, *opts;
/* *INDENT-ON* */
if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) { /*************************************************************************
for(i = 0; i < UCODE_SIZE; i++) * CPUSaver parameters
*
* All CPUSaver parameters are 16-bit literals that are part of a
* "move immediate value" instruction. By changing the value of
* the literal in the instruction before the code is loaded, the
* driver can change the algorithm.
*
* INTDELAY - This loads the dead-man timer with its inital value.
* When this timer expires the interrupt is asserted, and the
* timer is reset each time a new packet is received. (see
* BUNDLEMAX below to set the limit on number of chained packets)
* The current default is 0x600 or 1536. Experiments show that
* the value should probably stay within the 0x200 - 0x1000.
*
* BUNDLEMAX -
* This sets the maximum number of frames that will be bundled. In
* some situations, such as the TCP windowing algorithm, it may be
* better to limit the growth of the bundle size than let it go as
* high as it can, because that could cause too much added latency.
* The default is six, because this is the number of packets in the
* default TCP window size. A value of 1 would make CPUSaver indicate
* an interrupt for every frame received. If you do not want to put
* a limit on the bundle size, set this value to xFFFF.
*
* BUNDLESMALL -
* This contains a bit-mask describing the minimum size frame that
* will be bundled. The default masks the lower 7 bits, which means
* that any frame less than 128 bytes in length will not be bundled,
* but will instead immediately generate an interrupt. This does
* not affect the current bundle in any way. Any frame that is 128
* bytes or large will be bundled normally. This feature is meant
* to provide immediate indication of ACK frames in a TCP environment.
* Customers were seeing poor performance when a machine with CPUSaver
* enabled was sending but not receiving. The delay introduced when
* the ACKs were received was enough to reduce total throughput, because
* the sender would sit idle until the ACK was finally seen.
*
* The current default is 0xFF80, which masks out the lower 7 bits.
* This means that any frame which is x7F (127) bytes or smaller
* will cause an immediate interrupt. Because this value must be a
* bit mask, there are only a few valid values that can be used. To
* turn this feature off, the driver can write the value xFFFF to the
* lower word of this instruction (in the same way that the other
* parameters are used). Likewise, a value of 0xF800 (2047) would
* cause an interrupt to be generated for every frame, because all
* standard Ethernet frames are <= 2047 bytes in length.
*************************************************************************/
/* if you wish to disable the ucode functionality, while maintaining the
* workarounds it provides, set the following defines to:
* BUNDLESMALL 0
* BUNDLEMAX 1
* INTDELAY 1
*/
#define BUNDLESMALL 1
#define BUNDLEMAX (u16)6
#define INTDELAY (u16)1536 /* 0x600 */
/* do not load u-code for ICH devices */
if (nic->flags & ich)
goto noloaducode;
/* Search for ucode match against h/w rev_id */
for (opts = ucode_opts; opts->mac; opts++) {
int i;
u32 *ucode = opts->ucode;
if (nic->mac != opts->mac)
continue;
/* Insert user-tunable settings */
ucode[opts->timer_dword] &= 0xFFFF0000;
ucode[opts->timer_dword] |= INTDELAY;
ucode[opts->bundle_dword] &= 0xFFFF0000;
ucode[opts->bundle_dword] |= BUNDLEMAX;
ucode[opts->min_size_dword] &= 0xFFFF0000;
ucode[opts->min_size_dword] |= (BUNDLESMALL) ? 0xFFFF : 0xFF80;
for (i = 0; i < UCODE_SIZE; i++)
cb->u.ucode[i] = cpu_to_le32(ucode[i]); cb->u.ucode[i] = cpu_to_le32(ucode[i]);
cb->command = cpu_to_le16(cb_ucode); cb->command = cpu_to_le16(cb_ucode);
} else return;
cb->command = cpu_to_le16(cb_nop); }
noloaducode:
cb->command = cpu_to_le16(cb_nop);
} }
static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,

View File

@ -1,6 +1,6 @@
config FEC_8XX config FEC_8XX
tristate "Motorola 8xx FEC driver" tristate "Motorola 8xx FEC driver"
depends on NET_ETHERNET && FEC depends on NET_ETHERNET && 8xx
select MII select MII
config FEC_8XX_GENERIC_PHY config FEC_8XX_GENERIC_PHY

View File

@ -1360,7 +1360,7 @@ static struct pci_driver ioc3_driver = {
static int __init ioc3_init_module(void) static int __init ioc3_init_module(void)
{ {
return pci_module_init(&ioc3_driver); return pci_register_driver(&ioc3_driver);
} }
static void __exit ioc3_cleanup_module(void) static void __exit ioc3_cleanup_module(void)

View File

@ -1346,10 +1346,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
} else { } else {
if (netif_msg_probe(tp)) { if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX printk(KERN_ERR PFX
"Cannot find PowerManagement capability. " "PowerManagement capability not found.\n");
"Aborting.\n");
} }
goto err_out_mwi;
} }
/* make sure PCI base addr 1 is MMIO */ /* make sure PCI base addr 1 is MMIO */
@ -2516,7 +2514,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
} while (boguscnt > 0); } while (boguscnt > 0);
if (boguscnt <= 0) { if (boguscnt <= 0) {
if (net_ratelimit() && netif_msg_intr(tp)) { if (netif_msg_intr(tp) && net_ratelimit() ) {
printk(KERN_WARNING printk(KERN_WARNING
"%s: Too much work at interrupt!\n", dev->name); "%s: Too much work at interrupt!\n", dev->name);
} }

View File

@ -1,6 +1,7 @@
/* /*
* Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000, 2005 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. * Authors: Carsten Langgaard <carstenl@mips.com>
* Maciej W. Rozycki <macro@mips.com>
* *
* ######################################################################## * ########################################################################
* *
@ -265,6 +266,7 @@
/* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */ /* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
#define SAA9730_LAN_REGS_ADDR 0x20400 #define SAA9730_LAN_REGS_ADDR 0x20400
#define SAA9730_LAN_REGS_SIZE 0x00400
struct lan_saa9730_regmap { struct lan_saa9730_regmap {
volatile unsigned int TxBuffA; /* 0x20400 */ volatile unsigned int TxBuffA; /* 0x20400 */
@ -309,6 +311,7 @@ typedef volatile struct lan_saa9730_regmap t_lan_saa9730_regmap;
/* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */ /* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
#define SAA9730_EVM_REGS_ADDR 0x02000 #define SAA9730_EVM_REGS_ADDR 0x02000
#define SAA9730_EVM_REGS_SIZE 0x00400
struct evm_saa9730_regmap { struct evm_saa9730_regmap {
volatile unsigned int InterruptStatus1; /* 0x2000 */ volatile unsigned int InterruptStatus1; /* 0x2000 */
@ -329,16 +332,32 @@ typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
struct lan_saa9730_private { struct lan_saa9730_private {
/*
* Rx/Tx packet buffers.
* The Rx and Tx packets must be PACKET_SIZE aligned.
*/
void *buffer_start;
unsigned int buffer_size;
/*
* DMA address of beginning of this object, returned
* by pci_alloc_consistent().
*/
dma_addr_t dma_addr;
/* Pointer to the associated pci device structure */
struct pci_dev *pci_dev;
/* Pointer for the SAA9730 LAN controller register set. */ /* Pointer for the SAA9730 LAN controller register set. */
t_lan_saa9730_regmap *lan_saa9730_regs; t_lan_saa9730_regmap *lan_saa9730_regs;
/* Pointer to the SAA9730 EVM register. */ /* Pointer to the SAA9730 EVM register. */
t_evm_saa9730_regmap *evm_saa9730_regs; t_evm_saa9730_regmap *evm_saa9730_regs;
/* TRUE if the next buffer to write is RxBuffA, FALSE if RxBuffB. */
unsigned char NextRcvToUseIsA;
/* Rcv buffer Index. */ /* Rcv buffer Index. */
unsigned char NextRcvPacketIndex; unsigned char NextRcvPacketIndex;
/* Next buffer index. */
unsigned char NextRcvBufferIndex;
/* Index of next packet to use in that buffer. */ /* Index of next packet to use in that buffer. */
unsigned char NextTxmPacketIndex; unsigned char NextTxmPacketIndex;
@ -353,13 +372,8 @@ struct lan_saa9730_private {
unsigned char DmaRcvPackets; unsigned char DmaRcvPackets;
unsigned char DmaTxmPackets; unsigned char DmaTxmPackets;
unsigned char RcvAIndex; /* index into RcvBufferSpace[] for Blk A */ void *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
unsigned char RcvBIndex; /* index into RcvBufferSpace[] for Blk B */ void *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
unsigned int
TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
unsigned int
RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
unsigned int TxBufferFree[LAN_SAA9730_BUFFERS]; unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6]; unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];

View File

@ -154,6 +154,12 @@ MODULE_LICENSE("GPL");
*/ */
#define MEMORY_WAIT_TIME 16 #define MEMORY_WAIT_TIME 16
/*
* The maximum number of processing loops allowed for each call to the
* IRQ handler.
*/
#define MAX_IRQ_LOOPS 8
/* /*
* This selects whether TX packets are sent one by one to the SMC91x internal * This selects whether TX packets are sent one by one to the SMC91x internal
* memory and throttled until transmission completes. This may prevent * memory and throttled until transmission completes. This may prevent
@ -684,7 +690,6 @@ static void smc_hardware_send_pkt(unsigned long data)
/* queue the packet for TX */ /* queue the packet for TX */
SMC_SET_MMU_CMD(MC_ENQUEUE); SMC_SET_MMU_CMD(MC_ENQUEUE);
SMC_ACK_INT(IM_TX_EMPTY_INT);
smc_special_unlock(&lp->lock); smc_special_unlock(&lp->lock);
dev->trans_start = jiffies; dev->trans_start = jiffies;
@ -1207,6 +1212,7 @@ static void smc_phy_configure(void *data)
smc_phy_check_media(dev, 1); smc_phy_check_media(dev, 1);
smc_phy_configure_exit: smc_phy_configure_exit:
SMC_SELECT_BANK(2);
spin_unlock_irq(&lp->lock); spin_unlock_irq(&lp->lock);
lp->work_pending = 0; lp->work_pending = 0;
} }
@ -1305,7 +1311,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
SMC_SET_INT_MASK(0); SMC_SET_INT_MASK(0);
/* set a timeout value, so I don't stay here forever */ /* set a timeout value, so I don't stay here forever */
timeout = 8; timeout = MAX_IRQ_LOOPS;
do { do {
status = SMC_GET_INT(); status = SMC_GET_INT();
@ -1372,10 +1378,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* restore register states */ /* restore register states */
SMC_SET_PTR(saved_pointer); SMC_SET_PTR(saved_pointer);
SMC_SET_INT_MASK(mask); SMC_SET_INT_MASK(mask);
spin_unlock(&lp->lock); spin_unlock(&lp->lock);
DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout); if (timeout == MAX_IRQ_LOOPS)
PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
dev->name, mask);
DBG(3, "%s: Interrupt done (%d loops)\n",
dev->name, MAX_IRQ_LOOPS - timeout);
/* /*
* We return IRQ_HANDLED unconditionally here even if there was * We return IRQ_HANDLED unconditionally here even if there was

View File

@ -192,7 +192,9 @@ static int cisco_rx(struct sk_buff *skb)
"uptime %ud%uh%um%us)\n", "uptime %ud%uh%um%us)\n",
dev->name, days, hrs, dev->name, days, hrs,
min, sec); min, sec);
#if 0
netif_carrier_on(dev); netif_carrier_on(dev);
#endif
hdlc->state.cisco.up = 1; hdlc->state.cisco.up = 1;
} }
} }
@ -225,7 +227,9 @@ static void cisco_timer(unsigned long arg)
hdlc->state.cisco.settings.timeout * HZ)) { hdlc->state.cisco.settings.timeout * HZ)) {
hdlc->state.cisco.up = 0; hdlc->state.cisco.up = 0;
printk(KERN_INFO "%s: Link down\n", dev->name); printk(KERN_INFO "%s: Link down\n", dev->name);
#if 0
netif_carrier_off(dev); netif_carrier_off(dev);
#endif
} }
cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
@ -261,8 +265,10 @@ static void cisco_stop(struct net_device *dev)
{ {
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
del_timer_sync(&hdlc->state.cisco.timer); del_timer_sync(&hdlc->state.cisco.timer);
#if 0
if (netif_carrier_ok(dev)) if (netif_carrier_ok(dev))
netif_carrier_off(dev); netif_carrier_off(dev);
#endif
hdlc->state.cisco.up = 0; hdlc->state.cisco.up = 0;
hdlc->state.cisco.request_sent = 0; hdlc->state.cisco.request_sent = 0;
} }

View File

@ -545,8 +545,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
hdlc->state.fr.reliable = reliable; hdlc->state.fr.reliable = reliable;
if (reliable) { if (reliable) {
#if 0
if (!netif_carrier_ok(dev)) if (!netif_carrier_ok(dev))
netif_carrier_on(dev); netif_carrier_on(dev);
#endif
hdlc->state.fr.n391cnt = 0; /* Request full status */ hdlc->state.fr.n391cnt = 0; /* Request full status */
hdlc->state.fr.dce_changed = 1; hdlc->state.fr.dce_changed = 1;
@ -560,8 +562,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
} }
} }
} else { } else {
#if 0
if (netif_carrier_ok(dev)) if (netif_carrier_ok(dev))
netif_carrier_off(dev); netif_carrier_off(dev);
#endif
while (pvc) { /* Deactivate all PVCs */ while (pvc) { /* Deactivate all PVCs */
pvc_carrier(0, pvc); pvc_carrier(0, pvc);

View File

@ -79,11 +79,13 @@ static void __hdlc_set_carrier_on(struct net_device *dev)
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
if (hdlc->proto.start) if (hdlc->proto.start)
return hdlc->proto.start(dev); return hdlc->proto.start(dev);
#if 0
#ifdef DEBUG_LINK #ifdef DEBUG_LINK
if (netif_carrier_ok(dev)) if (netif_carrier_ok(dev))
printk(KERN_ERR "hdlc_set_carrier_on(): already on\n"); printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
#endif #endif
netif_carrier_on(dev); netif_carrier_on(dev);
#endif
} }
@ -94,11 +96,13 @@ static void __hdlc_set_carrier_off(struct net_device *dev)
if (hdlc->proto.stop) if (hdlc->proto.stop)
return hdlc->proto.stop(dev); return hdlc->proto.stop(dev);
#if 0
#ifdef DEBUG_LINK #ifdef DEBUG_LINK
if (!netif_carrier_ok(dev)) if (!netif_carrier_ok(dev))
printk(KERN_ERR "hdlc_set_carrier_off(): already off\n"); printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
#endif #endif
netif_carrier_off(dev); netif_carrier_off(dev);
#endif
} }
@ -294,8 +298,10 @@ int register_hdlc_device(struct net_device *dev)
if (result != 0) if (result != 0)
return -EIO; return -EIO;
#if 0
if (netif_carrier_ok(dev)) if (netif_carrier_ok(dev))
netif_carrier_off(dev); /* no carrier until DCD goes up */ netif_carrier_off(dev); /* no carrier until DCD goes up */
#endif
return 0; return 0;
} }

Some files were not shown because too many files have changed in this diff Show More