mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-12 13:34:10 +08:00
This commit is contained in:
commit
899a1fc084
12
CREDITS
12
CREDITS
@ -611,8 +611,7 @@ S: USA
|
||||
N: Randolph Chung
|
||||
E: tausq@debian.org
|
||||
D: Linux/PA-RISC hacker
|
||||
S: Los Altos, CA 94022
|
||||
S: USA
|
||||
S: Hong Kong
|
||||
|
||||
N: Juan Jose Ciarlante
|
||||
W: http://juanjox.kernelnotes.org/
|
||||
@ -3405,6 +3404,15 @@ S: Chudenicka 8
|
||||
S: 10200 Prague 10, Hostivar
|
||||
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
|
||||
E: hessu@cs.tut.fi
|
||||
D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks
|
||||
|
@ -237,8 +237,10 @@ X!Ilib/string.c
|
||||
<sect1><title>Driver Support</title>
|
||||
!Enet/core/dev.c
|
||||
!Enet/ethernet/eth.c
|
||||
!Einclude/linux/etherdevice.h
|
||||
!Enet/core/wireless.c
|
||||
!Iinclude/linux/etherdevice.h
|
||||
<!-- FIXME: Removed for now since no structured comments in source
|
||||
X!Enet/core/wireless.c
|
||||
-->
|
||||
</sect1>
|
||||
<sect1><title>Synchronous PPP</title>
|
||||
!Edrivers/net/wan/syncppp.c
|
||||
|
@ -1,7 +1,7 @@
|
||||
Kernel Memory Layout on ARM Linux
|
||||
|
||||
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
|
||||
kernel uses for ARM processors. It indicates which regions are
|
||||
@ -37,6 +37,8 @@ ff000000 ffbfffff Reserved for future expansion of DMA
|
||||
mapping region.
|
||||
|
||||
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.
|
||||
Memory returned by vmalloc/ioremap will
|
||||
|
@ -2907,6 +2907,11 @@ M: zaga@fly.cc.fer.hr
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
WISTRON LAPTOP BUTTON DRIVER
|
||||
P: Miloslav Trmac
|
||||
M: mitr@volny.cz
|
||||
S: Maintained
|
||||
|
||||
WL3501 WIRELESS PCMCIA CARD DRIVER
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@conectiva.com.br
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 15
|
||||
EXTRAVERSION =-rc1
|
||||
EXTRAVERSION =-rc2
|
||||
NAME=Affluent Albatross
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -120,7 +120,6 @@ EXPORT_SYMBOL(__arch_strncpy_from_user);
|
||||
EXPORT_SYMBOL(__get_user_1);
|
||||
EXPORT_SYMBOL(__get_user_2);
|
||||
EXPORT_SYMBOL(__get_user_4);
|
||||
EXPORT_SYMBOL(__get_user_8);
|
||||
|
||||
EXPORT_SYMBOL(__put_user_1);
|
||||
EXPORT_SYMBOL(__put_user_2);
|
||||
|
@ -48,8 +48,7 @@ work_pending:
|
||||
mov r0, sp @ 'regs'
|
||||
mov r2, why @ 'syscall'
|
||||
bl do_notify_resume
|
||||
disable_irq @ disable interrupts
|
||||
b no_work_pending
|
||||
b ret_slow_syscall @ Check work again
|
||||
|
||||
work_resched:
|
||||
bl schedule
|
||||
|
@ -595,23 +595,22 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
||||
*/
|
||||
ret |= !valid_user_regs(regs);
|
||||
|
||||
/*
|
||||
* Block the signal if we were unsuccessful.
|
||||
*/
|
||||
if (ret != 0) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -172,6 +172,10 @@ SECTIONS
|
||||
.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((__arch_info_end - __arch_info_begin), "no machine record defined")
|
||||
|
@ -54,15 +54,6 @@ __get_user_4:
|
||||
mov r0, #0
|
||||
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:
|
||||
mov r2, #0
|
||||
mov r0, #-EFAULT
|
||||
@ -73,6 +64,4 @@ __get_user_bad:
|
||||
.long 2b, __get_user_bad
|
||||
.long 3b, __get_user_bad
|
||||
.long 4b, __get_user_bad
|
||||
.long 5b, __get_user_bad_8
|
||||
.long 6b, __get_user_bad_8
|
||||
.previous
|
||||
|
@ -260,7 +260,7 @@ static void __init clps7500_init_irq(void)
|
||||
|
||||
static struct map_desc cl7500_io_desc[] __initdata = {
|
||||
{ /* IO space */
|
||||
.virtual = IO_BASE,
|
||||
.virtual = (unsigned long)IO_BASE,
|
||||
.pfn = __phys_to_pfn(IO_START),
|
||||
.length = IO_SIZE,
|
||||
.type = MT_DEVICE
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -293,7 +293,8 @@ static void __init get_assabet_scr(void)
|
||||
GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
|
||||
GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
|
||||
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 */
|
||||
scr &= 0x3fc; /* save as system configuration byte. */
|
||||
SCR_value = scr;
|
||||
|
@ -51,4 +51,4 @@ obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
|
||||
obj-$(CONFIG_CPU_SA110) += proc-sa110.o
|
||||
obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
|
||||
obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
|
||||
obj-$(CONFIG_CPU_V6) += proc-v6.o blockops.o
|
||||
obj-$(CONFIG_CPU_V6) += proc-v6.o
|
||||
|
@ -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);
|
@ -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
|
||||
* 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
|
||||
* 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)
|
||||
{
|
||||
@ -428,6 +429,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
|
||||
unsigned long addr;
|
||||
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)
|
||||
pmd_clear(pmd_off_k(addr));
|
||||
|
||||
@ -461,12 +468,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
|
||||
create_mapping(&map);
|
||||
#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
|
||||
* 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();
|
||||
|
||||
/*
|
||||
* Finally flush the tlb again - this ensures that we're in a
|
||||
* consistent state wrt the writebuffer if the writebuffer needs
|
||||
* draining. After this point, we can start to touch devices
|
||||
* again.
|
||||
* Finally flush the caches and tlb to ensure that we're in a
|
||||
* consistent state wrt the writebuffer. This also ensures that
|
||||
* any write-allocated cache lines in the vector page are written
|
||||
* back. After this point, we can start to touch devices again.
|
||||
*/
|
||||
local_flush_tlb_all();
|
||||
flush_cache_all();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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.
|
||||
*/
|
||||
void __iomem *
|
||||
__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
|
||||
unsigned long align)
|
||||
__ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
|
||||
{
|
||||
void * addr;
|
||||
struct vm_struct * area;
|
||||
|
@ -248,9 +248,7 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
|
||||
|
||||
acpi_table_print_madt_entry(header);
|
||||
|
||||
/* no utility in registering a disabled processor */
|
||||
if (processor->flags.enabled == 0)
|
||||
return 0;
|
||||
/* Register even disabled CPUs for cpu hotplug */
|
||||
|
||||
x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
|
||||
|
||||
|
@ -220,8 +220,9 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
|
||||
num_processors++;
|
||||
|
||||
if ((num_processors > 8) &&
|
||||
APIC_XAPIC(ver) &&
|
||||
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
|
||||
((APIC_XAPIC(ver) &&
|
||||
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ||
|
||||
(boot_cpu_data.x86_vendor == X86_VENDOR_AMD)))
|
||||
def_to_bigsmp = 1;
|
||||
else
|
||||
def_to_bigsmp = 0;
|
||||
|
@ -137,6 +137,7 @@ retry_bteop:
|
||||
bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
|
||||
|
||||
if (bte == NULL) {
|
||||
nasid_index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -492,6 +492,9 @@ static struct proc_dir_entry *proc_sn2_ptc;
|
||||
|
||||
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))) {
|
||||
printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
|
||||
return -EINVAL;
|
||||
|
@ -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) {
|
||||
memset(p, 0, a.sz);
|
||||
for (i = 0; i < nobj; i++) {
|
||||
int cpuobj_index = 0;
|
||||
if (!SN_HWPERF_IS_NODE(objs + i))
|
||||
continue;
|
||||
node = sn_hwperf_obj_to_cnode(objs + i);
|
||||
for_each_online_cpu(j) {
|
||||
if (node != cpu_to_node(j))
|
||||
continue;
|
||||
cpuobj = (struct sn_hwperf_object_info *) p + j;
|
||||
cpuobj = (struct sn_hwperf_object_info *) p + cpuobj_index++;
|
||||
slice = 'a' + cpuid_to_slice(j);
|
||||
cdata = cpu_data(j);
|
||||
cpuobj->id = j;
|
||||
|
@ -499,8 +499,12 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
|
||||
|
||||
dev = create_parisc_device(mod_path);
|
||||
if (dev->id.hw_type != HPHW_FAULTY) {
|
||||
printk("Two devices have hardware path %s. Please file a bug with HP.\n"
|
||||
"In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
|
||||
printk(KERN_ERR "Two devices have hardware path [%s]. "
|
||||
"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;
|
||||
}
|
||||
|
||||
|
@ -1846,6 +1846,7 @@ sys_clone_wrapper:
|
||||
ldo -16(%r30),%r29 /* Reference param save area */
|
||||
#endif
|
||||
|
||||
/* WARNING - Clobbers r19 and r21, userspace must save these! */
|
||||
STREG %r2,PT_GR19(%r1) /* save for child */
|
||||
STREG %r30,PT_GR21(%r1)
|
||||
BL sys_clone,%r2
|
||||
|
@ -188,7 +188,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
|
||||
temp = pa_pdc_cell.cba;
|
||||
dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
|
||||
if (!dev) {
|
||||
return PDC_NE_MOD;
|
||||
return PDC_OK;
|
||||
}
|
||||
|
||||
/* alloc_pa_dev sets dev->hpa */
|
||||
|
@ -19,536 +19,6 @@
|
||||
#define CODE
|
||||
#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 COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl)
|
||||
|
||||
@ -561,11 +31,6 @@ IOCTL_TABLE_START
|
||||
#define DECLARES
|
||||
#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 */
|
||||
HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
|
||||
HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
|
||||
@ -590,17 +55,6 @@ HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
|
||||
COMPATIBLE_IOCTL(RTC_EPOCH_SET)
|
||||
#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
|
||||
|
||||
int ioctl_table_size = ARRAY_SIZE(ioctl_start);
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/smp.h>
|
||||
|
||||
#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 void cpu_set_eiem(void *info)
|
||||
{
|
||||
set_eiem((unsigned long) info);
|
||||
}
|
||||
|
||||
static inline void cpu_disable_irq(unsigned int irq)
|
||||
static void cpu_disable_irq(unsigned int irq)
|
||||
{
|
||||
unsigned long eirr_bit = EIEM_MASK(irq);
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned long eirr_bit = EIEM_MASK(irq);
|
||||
|
||||
mtctl(eirr_bit, 23); /* clear EIRR bit before unmasking */
|
||||
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)
|
||||
@ -74,6 +85,35 @@ static unsigned int cpu_startup_irq(unsigned int irq)
|
||||
void no_ack_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 = {
|
||||
.typename = "CPU",
|
||||
.startup = cpu_startup_irq,
|
||||
@ -82,7 +122,9 @@ static struct hw_interrupt_type cpu_interrupt_type = {
|
||||
.disable = cpu_disable_irq,
|
||||
.ack = no_ack_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)
|
||||
@ -219,6 +261,17 @@ int txn_alloc_irq(unsigned int bits_wide)
|
||||
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)
|
||||
{
|
||||
static int next_cpu = -1;
|
||||
@ -233,7 +286,7 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
|
||||
if (next_cpu >= NR_CPUS)
|
||||
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();
|
||||
|
||||
/*
|
||||
* Only allow interrupt processing to be interrupted by the
|
||||
* timer tick
|
||||
* Don't allow TIMER or IPI nested interrupts.
|
||||
* 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)
|
||||
* 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)
|
||||
break;
|
||||
|
||||
if (eirr_val & EIEM_MASK(TIMER_IRQ))
|
||||
set_eiem(0);
|
||||
|
||||
mtctl(eirr_val, 23); /* reset bits we are going to process */
|
||||
|
||||
/* Work our way from MSb to LSb...same order we alloc EIRs */
|
||||
for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
|
||||
#ifdef CONFIG_SMP
|
||||
cpumask_t dest = irq_affinity[irq];
|
||||
#endif
|
||||
if (!(bit & eirr_val))
|
||||
continue;
|
||||
|
||||
/* clear bit in mask - can exit loop sooner */
|
||||
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);
|
||||
}
|
||||
}
|
||||
set_eiem(cpu_eiem);
|
||||
|
||||
set_eiem(cpu_eiem); /* restore original mask */
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
@ -291,12 +363,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
|
||||
static struct irqaction timer_action = {
|
||||
.handler = timer_interrupt,
|
||||
.name = "timer",
|
||||
.flags = SA_INTERRUPT,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static struct irqaction ipi_action = {
|
||||
.handler = ipi_interrupt,
|
||||
.name = "IPI",
|
||||
.flags = SA_INTERRUPT,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -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_write(struct file *file, const char __user *buf, size_t count,
|
||||
loff_t *ppos);
|
||||
static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||
static void perf_start_counters(void);
|
||||
static int perf_stop_counters(uint32_t *raddr);
|
||||
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.
|
||||
*/
|
||||
|
||||
static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
long error_start;
|
||||
uint32_t raddr[4];
|
||||
uint32_t raddr[4];
|
||||
int error = 0;
|
||||
|
||||
lock_kernel();
|
||||
switch (cmd) {
|
||||
|
||||
case PA_PERF_ON:
|
||||
/* Start the counters */
|
||||
perf_start_counters();
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case PA_PERF_OFF:
|
||||
error_start = perf_stop_counters(raddr);
|
||||
if (error_start != 0) {
|
||||
printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
|
||||
return -EFAULT;
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy out the Counters */
|
||||
if (copy_to_user((void __user *)arg, raddr,
|
||||
sizeof (raddr)) != 0) {
|
||||
return -EFAULT;
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case PA_PERF_VERSION:
|
||||
/* Return the version # */
|
||||
return put_user(PERF_VERSION, (int *)arg);
|
||||
error = put_user(PERF_VERSION, (int *)arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
error = -ENOTTY;
|
||||
}
|
||||
return -ENOTTY;
|
||||
|
||||
unlock_kernel();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct file_operations perf_fops = {
|
||||
.llseek = no_llseek,
|
||||
.read = perf_read,
|
||||
.write = perf_write,
|
||||
.ioctl = perf_ioctl,
|
||||
.unlocked_ioctl = perf_ioctl,
|
||||
.compat_ioctl = perf_ioctl,
|
||||
.open = perf_open,
|
||||
.release = perf_release
|
||||
};
|
||||
|
@ -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
|
||||
* that it wants to exit.
|
||||
*/
|
||||
ret = 0;
|
||||
DBG("sys_ptrace(KILL)\n");
|
||||
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
|
||||
goto out_tsk;
|
||||
@ -344,11 +345,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
|
||||
case PTRACE_GETEVENTMSG:
|
||||
ret = put_user(child->ptrace_message, (unsigned int __user *) data);
|
||||
goto out;
|
||||
goto out_tsk;
|
||||
|
||||
default:
|
||||
ret = ptrace_request(child, request, addr, data);
|
||||
goto out;
|
||||
goto out_tsk;
|
||||
}
|
||||
|
||||
out_wake_notrap:
|
||||
|
@ -296,7 +296,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
struct rt_sigframe __user *frame;
|
||||
unsigned long rp, usp;
|
||||
unsigned long haddr, sigframe_size;
|
||||
struct siginfo si;
|
||||
int err = 0;
|
||||
#ifdef __LP64__
|
||||
compat_int_t compat_val;
|
||||
|
@ -181,12 +181,19 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
while (ops) {
|
||||
unsigned long which = ffz(~ops);
|
||||
|
||||
ops &= ~(1 << 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:
|
||||
#if (kDEBUG>=100)
|
||||
printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
|
||||
#endif /* kDEBUG */
|
||||
ops &= ~(1 << IPI_RESCHEDULE);
|
||||
/*
|
||||
* Reschedule callback. Everything to be
|
||||
* 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)
|
||||
printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
|
||||
#endif /* kDEBUG */
|
||||
ops &= ~(1 << IPI_CALL_FUNC);
|
||||
{
|
||||
volatile struct smp_call_struct *data;
|
||||
void (*func)(void *info);
|
||||
@ -231,7 +237,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
#if (kDEBUG>=100)
|
||||
printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
|
||||
#endif /* kDEBUG */
|
||||
ops &= ~(1 << IPI_CPU_START);
|
||||
#ifdef ENTRY_SYS_CPUS
|
||||
p->state = STATE_RUNNING;
|
||||
#endif
|
||||
@ -241,7 +246,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
#if (kDEBUG>=100)
|
||||
printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
|
||||
#endif /* kDEBUG */
|
||||
ops &= ~(1 << IPI_CPU_STOP);
|
||||
#ifdef ENTRY_SYS_CPUS
|
||||
#else
|
||||
halt_processor();
|
||||
@ -252,13 +256,11 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
#if (kDEBUG>=100)
|
||||
printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
|
||||
#endif /* kDEBUG */
|
||||
ops &= ~(1 << IPI_CPU_TEST);
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
|
||||
this_cpu, which);
|
||||
ops &= ~(1 << which);
|
||||
return IRQ_NONE;
|
||||
} /* Switch */
|
||||
} /* while (ops) */
|
||||
@ -312,6 +314,12 @@ smp_send_start(void) { send_IPI_allbutself(IPI_CPU_START); }
|
||||
void
|
||||
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.
|
||||
@ -338,6 +346,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
|
||||
|
||||
/* Can deadlock when called with interrupts 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.info = info;
|
||||
|
@ -164,7 +164,7 @@ linux_gateway_entry:
|
||||
#endif
|
||||
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 %r22, TASK_PT_GR22(%r1)
|
||||
STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */
|
||||
@ -527,6 +527,7 @@ lws_compare_and_swap:
|
||||
We *must* giveup this call and fail.
|
||||
*/
|
||||
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 */
|
||||
cmpb,<>,n %r21, %r28, cas_lock /* Called recursive? */
|
||||
b lws_exit /* Return error! */
|
||||
|
@ -40,7 +40,7 @@
|
||||
#endif
|
||||
|
||||
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
|
||||
@ -55,11 +55,6 @@ static void fixup_resource(struct resource *res, struct pci_dev *dev);
|
||||
static void do_bus_setup(struct pci_bus *bus);
|
||||
#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.
|
||||
* 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
|
||||
@ -1186,17 +1181,6 @@ void phbs_remap_io(void)
|
||||
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)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(dev->bus);
|
||||
|
@ -146,9 +146,6 @@ EXPORT_SYMBOL(pci_bus_io_base);
|
||||
EXPORT_SYMBOL(pci_bus_io_base_phys);
|
||||
EXPORT_SYMBOL(pci_bus_mem_base_phys);
|
||||
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 */
|
||||
|
||||
#ifdef CONFIG_NOT_COHERENT_CACHE
|
||||
|
@ -36,8 +36,9 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <asm/ptrace-common.h>
|
||||
#include "ptrace-common.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
|
@ -33,7 +33,8 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/ptrace-common.h>
|
||||
|
||||
#include "ptrace-common.h"
|
||||
|
||||
/*
|
||||
* does not yet catch signals sent when the child dies.
|
||||
|
@ -14,9 +14,10 @@
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/imalloc.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include "mmu_decl.h"
|
||||
|
||||
static DECLARE_MUTEX(imlist_sem);
|
||||
struct vm_struct * imlist = NULL;
|
||||
|
||||
|
@ -64,7 +64,8 @@
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/vdso.h>
|
||||
#include <asm/imalloc.h>
|
||||
|
||||
#include "mmu_decl.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt...) printk(fmt)
|
||||
|
@ -33,7 +33,6 @@ extern void invalidate_tlbcam_entry(int index);
|
||||
|
||||
extern int __map_without_bats;
|
||||
extern unsigned long ioremap_base;
|
||||
extern unsigned long ioremap_bot;
|
||||
extern unsigned int rtas_data, rtas_size;
|
||||
|
||||
extern PTE *Hash, *Hash_end;
|
||||
@ -42,6 +41,7 @@ extern unsigned long Hash_size, Hash_mask;
|
||||
extern unsigned int num_tlbcam_entries;
|
||||
#endif
|
||||
|
||||
extern unsigned long ioremap_bot;
|
||||
extern unsigned long __max_low_memory;
|
||||
extern unsigned long __initial_memory_limit;
|
||||
extern unsigned long total_memory;
|
||||
@ -84,4 +84,16 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
|
||||
else
|
||||
_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
|
||||
|
@ -64,7 +64,8 @@
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/vdso.h>
|
||||
#include <asm/imalloc.h>
|
||||
|
||||
#include "mmu_decl.h"
|
||||
|
||||
unsigned long ioremap_bot = IMALLOC_BASE;
|
||||
static unsigned long phbs_io_bot = PHBS_IO_BASE;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/atomic.h>
|
||||
@ -631,8 +632,9 @@ void smp_core99_give_timebase(void)
|
||||
mb();
|
||||
|
||||
/* wait for the secondary to have taken it */
|
||||
for (t = 100000; t > 0 && sec_tb_reset; --t)
|
||||
udelay(10);
|
||||
/* note: can't use udelay here, since it needs the timebase running */
|
||||
for (t = 10000000; t > 0 && sec_tb_reset; --t)
|
||||
barrier();
|
||||
if (sec_tb_reset)
|
||||
/* XXX BUG_ON here? */
|
||||
printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
|
||||
|
@ -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);
|
||||
|
||||
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 */
|
||||
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);
|
||||
|
||||
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 */
|
||||
do {
|
||||
@ -735,12 +737,13 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
|
||||
|
||||
spin_lock_irqsave(&mpic_lock, flags);
|
||||
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,
|
||||
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
|
||||
} else {
|
||||
reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
|
||||
& MPIC_VECPRI_PRIORITY_MASK;
|
||||
reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
|
||||
& ~MPIC_VECPRI_PRIORITY_MASK;
|
||||
mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
|
||||
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* linux/drivers/block/as-iosched.c
|
||||
*
|
||||
* Anticipatory & deadline i/o scheduler.
|
||||
*
|
||||
* 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;
|
||||
int data_dir;
|
||||
|
||||
if (arq->state != AS_RQ_PRESCHED) {
|
||||
printk("arq->state: %d\n", arq->state);
|
||||
WARN_ON(1);
|
||||
}
|
||||
arq->state = AS_RQ_NEW;
|
||||
|
||||
if (rq_data_dir(arq->request) == READ
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* linux/drivers/block/cfq-iosched.c
|
||||
*
|
||||
* CFQ, or complete fairness queueing, disk scheduler.
|
||||
*
|
||||
* Based on ideas from a previously unfinished io
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* linux/drivers/block/deadline-iosched.c
|
||||
*
|
||||
* Deadline i/o scheduler.
|
||||
*
|
||||
* Copyright (C) 2002 Jens Axboe <axboe@suse.de>
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* linux/drivers/block/elevator.c
|
||||
*
|
||||
* Block device elevator/IO-scheduler.
|
||||
*
|
||||
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* linux/drivers/block/ll_rw_blk.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
* Copyright (C) 1994, Karl Keyte: Added support for disk statistics
|
||||
* Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
|
||||
|
@ -1017,10 +1017,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
|
||||
status = -ENOMEM;
|
||||
goto cleanup1;
|
||||
}
|
||||
if (ioc->Request.Type.Direction == XFER_WRITE &&
|
||||
copy_from_user(buff[sg_used], data_ptr, sz)) {
|
||||
if (ioc->Request.Type.Direction == XFER_WRITE) {
|
||||
if (copy_from_user(buff[sg_used], data_ptr, sz)) {
|
||||
status = -ENOMEM;
|
||||
goto cleanup1;
|
||||
goto cleanup1;
|
||||
}
|
||||
} else {
|
||||
memset(buff[sg_used], 0, sz);
|
||||
}
|
||||
@ -1138,8 +1139,15 @@ static int revalidate_allvol(ctlr_info_t *host)
|
||||
|
||||
for(i=0; i< NWD; i++) {
|
||||
struct gendisk *disk = host->gendisk[i];
|
||||
if (disk->flags & GENHD_FL_UP)
|
||||
del_gendisk(disk);
|
||||
if (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.
|
||||
*/
|
||||
if (h->gendisk[0] != disk){
|
||||
if (disk->flags & GENHD_FL_UP){
|
||||
blk_cleanup_queue(disk->queue);
|
||||
del_gendisk(disk);
|
||||
drv->queue = NULL;
|
||||
if (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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3225,9 +3236,14 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
|
||||
/* remove it from the disk list */
|
||||
for (j = 0; j < NWD; j++) {
|
||||
struct gendisk *disk = hba[i]->gendisk[j];
|
||||
if (disk->flags & GENHD_FL_UP) {
|
||||
del_gendisk(disk);
|
||||
blk_cleanup_queue(disk->queue);
|
||||
if (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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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},
|
||||
{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 },
|
||||
{256, 65536, 6, 0x00000008 },
|
||||
|
@ -97,7 +97,7 @@ void agp_backend_release(struct agp_bridge_data *bridge)
|
||||
EXPORT_SYMBOL(agp_backend_release);
|
||||
|
||||
|
||||
static struct { int mem, agp; } maxes_table[] = {
|
||||
static const struct { int mem, agp; } maxes_table[] = {
|
||||
{0, 0},
|
||||
{32, 4},
|
||||
{64, 28},
|
||||
|
@ -371,6 +371,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
|
||||
.device_id = PCI_DEVICE_ID_VIA_3296_0,
|
||||
.chipset_name = "P4M800",
|
||||
},
|
||||
/* P4M800CE */
|
||||
{
|
||||
.device_id = PCI_DEVICE_ID_VIA_P4M800CE,
|
||||
.chipset_name = "P4M800CE",
|
||||
},
|
||||
|
||||
{ }, /* 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_83_87XX_1),
|
||||
ID(PCI_DEVICE_ID_VIA_3296_0),
|
||||
ID(PCI_DEVICE_ID_VIA_P4M800CE),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -36,8 +36,6 @@
|
||||
#include <asm/hardware.h> /* Pick up IXP2000-specific bits */
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
static struct device_driver ixp2000_i2c_driver;
|
||||
|
||||
static inline int ixp2000_scl_pin(void *data)
|
||||
{
|
||||
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->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);
|
||||
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);
|
||||
|
||||
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);
|
||||
return err;
|
||||
}
|
||||
|
@ -35,8 +35,6 @@
|
||||
|
||||
#include <asm/hardware.h> /* Pick up IXP4xx-specific bits */
|
||||
|
||||
static struct platform_driver ixp4xx_i2c_driver;
|
||||
|
||||
static inline int ixp4xx_scl_pin(void *data)
|
||||
{
|
||||
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->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);
|
||||
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);
|
||||
|
||||
if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
|
||||
printk(KERN_ERR "ERROR: Could not install %s\n",
|
||||
plat_dev->dev.bus_id);
|
||||
printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id);
|
||||
|
||||
kfree(drv_data);
|
||||
return err;
|
||||
|
@ -625,7 +625,7 @@ config BLK_DEV_NS87415
|
||||
tristate "NS87415 chipset support"
|
||||
help
|
||||
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>.
|
||||
|
||||
|
@ -3328,8 +3328,8 @@ static ide_proc_entry_t idecd_proc[] = {
|
||||
#endif
|
||||
|
||||
static ide_driver_t ide_cdrom_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.gen_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ide-cdrom",
|
||||
.bus = &ide_bus_type,
|
||||
.probe = ide_cd_probe,
|
||||
@ -3510,8 +3510,8 @@ static void __exit ide_cdrom_exit(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -1089,8 +1089,8 @@ static void ide_device_shutdown(struct device *dev)
|
||||
}
|
||||
|
||||
static ide_driver_t idedisk_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.gen_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ide-disk",
|
||||
.bus = &ide_bus_type,
|
||||
.probe = ide_disk_probe,
|
||||
@ -1266,7 +1266,7 @@ static void __exit idedisk_exit (void)
|
||||
driver_unregister(&idedisk_driver.gen_driver);
|
||||
}
|
||||
|
||||
static int idedisk_init (void)
|
||||
static int __init idedisk_init(void)
|
||||
{
|
||||
return driver_register(&idedisk_driver.gen_driver);
|
||||
}
|
||||
|
@ -1925,8 +1925,8 @@ static ide_proc_entry_t idefloppy_proc[] = {
|
||||
static int ide_floppy_probe(struct device *);
|
||||
|
||||
static ide_driver_t idefloppy_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.gen_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ide-floppy",
|
||||
.bus = &ide_bus_type,
|
||||
.probe = ide_floppy_probe,
|
||||
@ -2191,10 +2191,7 @@ static void __exit idefloppy_exit (void)
|
||||
driver_unregister(&idefloppy_driver.gen_driver);
|
||||
}
|
||||
|
||||
/*
|
||||
* idefloppy_init will register the driver for each floppy.
|
||||
*/
|
||||
static int idefloppy_init (void)
|
||||
static int __init idefloppy_init(void)
|
||||
{
|
||||
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
|
||||
return driver_register(&idefloppy_driver.gen_driver);
|
||||
|
@ -1629,12 +1629,6 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
|
||||
* for the new rq to be completed. This is VERY DANGEROUS, and is
|
||||
* 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
|
||||
* request queue, and the function returns immediately without waiting
|
||||
* for the new rq to be completed. This is again intended for careful
|
||||
|
@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
|
||||
{
|
||||
u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */
|
||||
|
||||
if (on && drive->media == ide_disk) {
|
||||
if (!PCI_DMA_BUS_IS_PHYS)
|
||||
addr = BLK_BOUNCE_ANY;
|
||||
else if (HWIF(drive)->pci_dev)
|
||||
if (!PCI_DMA_BUS_IS_PHYS) {
|
||||
addr = BLK_BOUNCE_ANY;
|
||||
} else if (on && drive->media == ide_disk) {
|
||||
if (HWIF(drive)->pci_dev)
|
||||
addr = HWIF(drive)->pci_dev->dma_mask;
|
||||
}
|
||||
|
||||
|
@ -4748,8 +4748,8 @@ static ide_proc_entry_t idetape_proc[] = {
|
||||
static int ide_tape_probe(struct device *);
|
||||
|
||||
static ide_driver_t idetape_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.gen_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ide-tape",
|
||||
.bus = &ide_bus_type,
|
||||
.probe = ide_tape_probe,
|
||||
@ -4916,10 +4916,7 @@ static void __exit idetape_exit (void)
|
||||
unregister_chrdev(IDETAPE_MAJOR, "ht");
|
||||
}
|
||||
|
||||
/*
|
||||
* idetape_init will register the driver for each tape.
|
||||
*/
|
||||
static int idetape_init (void)
|
||||
static int __init idetape_init(void)
|
||||
{
|
||||
int error = 1;
|
||||
idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
|
||||
|
@ -51,8 +51,6 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define DEBUG_TASKFILE 0 /* unset when fixed */
|
||||
|
||||
static void ata_bswap_data (void *buffer, int wcount)
|
||||
{
|
||||
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);
|
||||
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
|
||||
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
|
||||
#if DEBUG_TASKFILE
|
||||
u8 status;
|
||||
#endif
|
||||
|
||||
if (task->data_phase == TASKFILE_MULTI_IN ||
|
||||
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 not set, then define default settings.
|
||||
* The default values are:
|
||||
* write and read all taskfile registers (except data)
|
||||
* write and read the hob registers (sector,nsector,lcyl,hcyl)
|
||||
* read all taskfile registers (except data)
|
||||
* 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) {
|
||||
task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
|
||||
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);
|
||||
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) {
|
||||
u16 data = taskfile->data + (hobfile->data << 8);
|
||||
hwif->OUTW(data, IDE_DATA_REG);
|
||||
|
@ -65,23 +65,6 @@ static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
|
||||
#define BUSCLOCK(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.
|
||||
@ -112,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
|
||||
switch(hwif->pci_dev->device) {
|
||||
case PCI_DEVICE_ID_ARTOP_ATP865:
|
||||
case PCI_DEVICE_ID_ARTOP_ATP865R:
|
||||
#if 0
|
||||
mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3;
|
||||
#else
|
||||
mode = (hwif->INB(((hwif->channel) ?
|
||||
hwif->mate->dma_status :
|
||||
hwif->dma_status)) & 0x10) ? 4 : 3;
|
||||
#endif
|
||||
break;
|
||||
case PCI_DEVICE_ID_ARTOP_ATP860:
|
||||
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_ATP865R:
|
||||
printk(" AEC62XX time out ");
|
||||
#if 0
|
||||
{
|
||||
int i = 0;
|
||||
u8 reg49h = 0;
|
||||
pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, ®49h);
|
||||
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:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 struct pci_device_id ati_rs100[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
|
||||
{ },
|
||||
};
|
||||
|
||||
ide_pci_device_t *d = &ali15x3_chipset;
|
||||
|
||||
if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL))
|
||||
printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");
|
||||
if (pci_dev_present(ati_rs100))
|
||||
printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
|
||||
|
||||
#if defined(CONFIG_SPARC64)
|
||||
d->init_hwif = init_hwif_common_ali15x3;
|
||||
|
@ -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
|
||||
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);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
pci_set_master(dev);
|
||||
if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
|
||||
|
@ -6,7 +6,13 @@
|
||||
*
|
||||
* 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:
|
||||
|
@ -87,6 +87,7 @@ static const struct {
|
||||
u8 chipset_family;
|
||||
u8 flags;
|
||||
} SiSHostChipInfo[] = {
|
||||
{ "SiS965", PCI_DEVICE_ID_SI_965, ATA_133 },
|
||||
{ "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 },
|
||||
{ "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 },
|
||||
{ "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 },
|
||||
|
@ -79,6 +79,7 @@ static struct via_isa_bridge {
|
||||
u8 rev_max;
|
||||
u16 flags;
|
||||
} 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 },
|
||||
{ "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 },
|
||||
@ -100,185 +101,14 @@ static struct via_isa_bridge {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static struct via_isa_bridge *via_config;
|
||||
static unsigned int via_80w;
|
||||
static unsigned int via_clock;
|
||||
static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
|
||||
|
||||
/*
|
||||
* 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)
|
||||
struct via82cxxx_dev
|
||||
{
|
||||
int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
|
||||
uen[4], udma[4], umul[4], active8b[4], recover8b[4];
|
||||
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 */
|
||||
struct via_isa_bridge *via_config;
|
||||
unsigned int via_80w;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
if (~via_config->flags & VIA_BAD_AST) {
|
||||
if (~vdev->via_config->flags & VIA_BAD_AST) {
|
||||
pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
|
||||
t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
|
||||
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),
|
||||
((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_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;
|
||||
@ -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)
|
||||
{
|
||||
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
|
||||
struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
|
||||
struct ide_timing t, p;
|
||||
unsigned int T, UT;
|
||||
|
||||
@ -337,7 +170,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
|
||||
|
||||
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_66: UT = T/2; 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);
|
||||
}
|
||||
|
||||
via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
|
||||
via_set_speed(HWIF(drive), drive->dn, &t);
|
||||
|
||||
if (!drive->init_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)
|
||||
{
|
||||
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,
|
||||
XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
|
||||
(via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
|
||||
(w80 && (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 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
|
||||
(vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
|
||||
(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
|
||||
(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
|
||||
(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
|
||||
|
||||
via_set_drive(drive, speed);
|
||||
|
||||
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
|
||||
return HWIF(drive)->ide_dma_on(drive);
|
||||
return HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
return hwif->ide_dma_on(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)
|
||||
{
|
||||
struct pci_dev *isa = NULL;
|
||||
struct via_isa_bridge *via_config;
|
||||
u8 t, v;
|
||||
unsigned int u;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Find the ISA bridge to see how good the IDE is.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
via_config = via_config_find(&isa);
|
||||
if (!via_config->id) {
|
||||
printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check 80-wire cable presence and setup Clk66.
|
||||
* Setup or disable Clk66 if appropriate
|
||||
*/
|
||||
|
||||
switch (via_config->flags & VIA_UDMA) {
|
||||
|
||||
case VIA_UDMA_66:
|
||||
/* Enable Clk66 */
|
||||
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
|
||||
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) {
|
||||
if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
|
||||
/* Enable Clk66 */
|
||||
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
|
||||
pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
|
||||
} else if (via_config->flags & VIA_BAD_CLK66) {
|
||||
/* Would cause trouble on 596a and 686 */
|
||||
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
|
||||
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],
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev),
|
||||
GFP_KERNEL);
|
||||
struct pci_dev *isa = NULL;
|
||||
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->tuneproc = &via82cxxx_tune_drive;
|
||||
@ -594,7 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
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].dn = hwif->channel * 2 + i;
|
||||
}
|
||||
@ -608,7 +460,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
|
||||
hwif->swdma_mask = 0x07;
|
||||
|
||||
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;
|
||||
if (!noautodma)
|
||||
hwif->autodma = 1;
|
||||
@ -616,24 +468,35 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
|
||||
hwif->drives[1].autodma = hwif->autodma;
|
||||
}
|
||||
|
||||
static ide_pci_device_t via82cxxx_chipset __devinitdata = {
|
||||
.name = "VP_IDE",
|
||||
.init_chipset = init_chipset_via82cxxx,
|
||||
.init_hwif = init_hwif_via82cxxx,
|
||||
.channels = 2,
|
||||
.autodma = NOAUTODMA,
|
||||
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
|
||||
.bootable = ON_BOARD,
|
||||
static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
|
||||
{ /* 0 */
|
||||
.name = "VP_IDE",
|
||||
.init_chipset = init_chipset_via82cxxx,
|
||||
.init_hwif = init_hwif_via82cxxx,
|
||||
.channels = 2,
|
||||
.autodma = NOAUTODMA,
|
||||
.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)
|
||||
{
|
||||
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[] = {
|
||||
{ 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_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, via_pci_tbl);
|
||||
|
@ -1401,20 +1401,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
|
||||
/* We probe the hwif now */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -787,7 +787,7 @@ static int pre_init = 1; /* Before first ordered IDE scan */
|
||||
static LIST_HEAD(ide_pci_drivers);
|
||||
|
||||
/*
|
||||
* __ide_register_pci_driver - attach IDE driver
|
||||
* __ide_pci_register_driver - attach IDE driver
|
||||
* @driver: pci driver
|
||||
* @module: owner module of the driver
|
||||
*
|
||||
|
@ -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 rmpp_active = 0;
|
||||
|
||||
if (count < sizeof (struct ib_user_mad))
|
||||
if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
|
||||
return -EINVAL;
|
||||
|
||||
length = count - sizeof (struct ib_user_mad);
|
||||
|
@ -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) {
|
||||
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
|
||||
* resources set to a non-zero value.
|
||||
* Only enable RDMA reads and atomics if we have
|
||||
* responder resources set to a non-zero value.
|
||||
*/
|
||||
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 |=
|
||||
cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
|
||||
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) {
|
||||
/*
|
||||
* Lowering our responder resources to zero.
|
||||
* Turn off RDMA/atomics as responder.
|
||||
* (RWE/RRE/RAE in params2 already zero)
|
||||
* Turn off reads RDMA and atomics as responder.
|
||||
* (RRE/RAE in params2 already zero)
|
||||
*/
|
||||
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
|
||||
MTHCA_QP_OPTPAR_RRE |
|
||||
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
|
||||
MTHCA_QP_OPTPAR_RAE);
|
||||
}
|
||||
|
||||
if (!qp->resp_depth && attr->max_dest_rd_atomic) {
|
||||
/*
|
||||
* 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 |=
|
||||
cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
|
||||
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 ?
|
||||
MTHCA_QP_BIT_RAE : 0);
|
||||
|
||||
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
|
||||
MTHCA_QP_OPTPAR_RRE |
|
||||
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
|
||||
MTHCA_QP_OPTPAR_RAE);
|
||||
}
|
||||
|
||||
@ -921,10 +918,12 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev,
|
||||
else
|
||||
qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
|
||||
|
||||
qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
|
||||
qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
|
||||
sizeof (struct mthca_next_seg)) /
|
||||
sizeof (struct mthca_data_seg);
|
||||
qp->sq.max_gs = min_t(int, dev->limits.max_sg,
|
||||
max_data_size / sizeof (struct mthca_data_seg));
|
||||
qp->rq.max_gs = min_t(int, dev->limits.max_sg,
|
||||
(min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
|
||||
sizeof (struct mthca_next_seg)) /
|
||||
sizeof (struct mthca_data_seg));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
* 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)
|
||||
{
|
||||
if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
|
||||
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];
|
||||
}
|
||||
|
||||
@ -823,11 +831,6 @@ static int __srp_post_send(struct srp_target_port *target,
|
||||
struct ib_send_wr wr, *bad_wr;
|
||||
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.length = len;
|
||||
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)
|
||||
return -ENOMEM;
|
||||
|
||||
target_host->max_lun = SRP_MAX_LUN;
|
||||
|
||||
target = host_to_target(target_host);
|
||||
memset(target, 0, sizeof *target);
|
||||
|
||||
|
@ -54,6 +54,7 @@ enum {
|
||||
SRP_PORT_REDIRECT = 1,
|
||||
SRP_DLID_REDIRECT = 2,
|
||||
|
||||
SRP_MAX_LUN = 512,
|
||||
SRP_MAX_IU_LEN = 256,
|
||||
|
||||
SRP_RQ_SHIFT = 6,
|
||||
|
@ -339,14 +339,20 @@ static struct gameport_event *gameport_get_event(void)
|
||||
return event;
|
||||
}
|
||||
|
||||
static void gameport_handle_events(void)
|
||||
static void gameport_handle_event(void)
|
||||
{
|
||||
struct gameport_event *event;
|
||||
struct gameport_driver *gameport_drv;
|
||||
|
||||
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) {
|
||||
case GAMEPORT_REGISTER_PORT:
|
||||
@ -433,7 +439,7 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
|
||||
static int gameport_thread(void *nothing)
|
||||
{
|
||||
do {
|
||||
gameport_handle_events();
|
||||
gameport_handle_event();
|
||||
wait_event_interruptible(gameport_wait,
|
||||
kthread_should_stop() || !list_empty(&gameport_event_list));
|
||||
try_to_freeze();
|
||||
|
@ -536,7 +536,7 @@ static struct attribute *input_dev_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group input_dev_group = {
|
||||
static struct attribute_group input_dev_attr_group = {
|
||||
.attrs = input_dev_attrs,
|
||||
};
|
||||
|
||||
@ -717,35 +717,14 @@ struct input_dev *input_allocate_device(void)
|
||||
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)
|
||||
{
|
||||
static atomic_t input_no = ATOMIC_INIT(0);
|
||||
struct input_handle *handle;
|
||||
struct input_handler *handler;
|
||||
struct input_device_id *id;
|
||||
const char *path;
|
||||
int error;
|
||||
|
||||
if (!dev->dynalloc) {
|
||||
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);
|
||||
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)
|
||||
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();
|
||||
|
||||
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)
|
||||
@ -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_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);
|
||||
|
||||
input_wakeup_procfs_readers();
|
||||
|
@ -166,6 +166,9 @@ static unsigned char atkbd_unxlate_table[128] = {
|
||||
|
||||
#define ATKBD_SPECIAL 248
|
||||
|
||||
#define ATKBD_LED_EVENT_BIT 0
|
||||
#define ATKBD_REP_EVENT_BIT 1
|
||||
|
||||
static struct {
|
||||
unsigned char keycode;
|
||||
unsigned char set2;
|
||||
@ -211,6 +214,10 @@ struct atkbd {
|
||||
unsigned char err_xl;
|
||||
unsigned int last;
|
||||
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,
|
||||
@ -424,58 +431,86 @@ out:
|
||||
}
|
||||
|
||||
/*
|
||||
* Event callback from the input module. Events that change the state of
|
||||
* the hardware are processed here.
|
||||
* atkbd_event_work() is used to complete processing of events that
|
||||
* 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] =
|
||||
{ 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 };
|
||||
const short delay[4] =
|
||||
{ 250, 500, 750, 1000 };
|
||||
|
||||
struct atkbd *atkbd = data;
|
||||
struct input_dev *dev = atkbd->dev;
|
||||
unsigned char param[2];
|
||||
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)
|
||||
return -1;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case EV_LED:
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
set_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask);
|
||||
wmb();
|
||||
schedule_work(&atkbd->event_work);
|
||||
return 0;
|
||||
|
||||
case EV_REP:
|
||||
|
||||
if (atkbd->softrepeat) return 0;
|
||||
|
||||
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_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
|
||||
if (!atkbd->softrepeat) {
|
||||
set_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask);
|
||||
wmb();
|
||||
schedule_work(&atkbd->event_work);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -810,6 +845,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
|
||||
|
||||
atkbd->dev = dev;
|
||||
ps2_init(&atkbd->ps2dev, serio);
|
||||
INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
|
||||
init_MUTEX(&atkbd->event_sem);
|
||||
|
||||
switch (serio->id.type) {
|
||||
|
||||
|
@ -40,6 +40,16 @@ config INPUT_M68K_BEEP
|
||||
tristate "M68k Beeper support"
|
||||
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
|
||||
tristate "User level driver support"
|
||||
help
|
||||
|
@ -9,4 +9,5 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
|
||||
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
|
||||
obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o
|
||||
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
|
||||
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
|
||||
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
|
||||
|
@ -92,24 +92,19 @@ static void uinput_request_done(struct uinput_device *udev, struct uinput_reques
|
||||
{
|
||||
/* Mark slot as available */
|
||||
udev->requests[request->id] = NULL;
|
||||
wake_up_interruptible(&udev->requests_waitq);
|
||||
wake_up(&udev->requests_waitq);
|
||||
|
||||
complete(&request->done);
|
||||
}
|
||||
|
||||
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 */
|
||||
uinput_dev_event(dev, EV_UINPUT, request->code, request->id);
|
||||
|
||||
/* Wait for the request to complete */
|
||||
retval = wait_for_completion_interruptible(&request->done);
|
||||
if (!retval)
|
||||
retval = request->retval;
|
||||
|
||||
return retval;
|
||||
wait_for_completion(&request->done);
|
||||
return request->retval;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!udev->dev->name) {
|
||||
int error;
|
||||
|
||||
if (udev->state != UIST_SETUP_COMPLETE) {
|
||||
printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
error = input_register_device(udev->dev);
|
||||
if (error) {
|
||||
uinput_destroy_device(udev);
|
||||
return error;
|
||||
}
|
||||
|
||||
input_unregister_device(udev->dev);
|
||||
|
||||
clear_bit(UIST_CREATED, &udev->state);
|
||||
udev->state = UIST_CREATED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uinput_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct uinput_device *newdev;
|
||||
struct input_dev *newinput;
|
||||
struct uinput_device *newdev;
|
||||
|
||||
newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
|
||||
newdev = kzalloc(sizeof(struct uinput_device), GFP_KERNEL);
|
||||
if (!newdev)
|
||||
goto error;
|
||||
memset(newdev, 0, sizeof(struct uinput_device));
|
||||
return -ENOMEM;
|
||||
|
||||
init_MUTEX(&newdev->sem);
|
||||
spin_lock_init(&newdev->requests_lock);
|
||||
init_waitqueue_head(&newdev->requests_waitq);
|
||||
|
||||
newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
|
||||
if (!newinput)
|
||||
goto cleanup;
|
||||
memset(newinput, 0, sizeof(struct input_dev));
|
||||
|
||||
newdev->dev = newinput;
|
||||
init_waitqueue_head(&newdev->waitq);
|
||||
newdev->state = UIST_NEW_DEVICE;
|
||||
|
||||
file->private_data = newdev;
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
kfree(newdev);
|
||||
error:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int uinput_validate_absbits(struct input_dev *dev)
|
||||
@ -246,34 +236,55 @@ static int uinput_validate_absbits(struct input_dev *dev)
|
||||
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 input_dev *dev;
|
||||
struct uinput_device *udev;
|
||||
char *name;
|
||||
int size;
|
||||
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;
|
||||
|
||||
user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL);
|
||||
if (!user_dev) {
|
||||
retval = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
if (!user_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
|
||||
retval = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
kfree(dev->name);
|
||||
|
||||
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);
|
||||
if (!name) {
|
||||
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
|
||||
* told in Documentation/input/input-programming.txt */
|
||||
if (test_bit(EV_ABS, dev->evbit)) {
|
||||
int err = uinput_validate_absbits(dev);
|
||||
if (err < 0) {
|
||||
retval = err;
|
||||
kfree(dev->name);
|
||||
}
|
||||
retval = uinput_validate_absbits(dev);
|
||||
if (retval < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
udev->state = UIST_SETUP_COMPLETE;
|
||||
retval = count;
|
||||
|
||||
exit:
|
||||
kfree(user_dev);
|
||||
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)
|
||||
{
|
||||
struct uinput_device *udev = file->private_data;
|
||||
int retval;
|
||||
|
||||
if (test_bit(UIST_CREATED, &udev->state)) {
|
||||
struct input_event ev;
|
||||
retval = down_interruptible(&udev->sem);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
|
||||
return -EFAULT;
|
||||
input_event(udev->dev, ev.type, ev.code, ev.value);
|
||||
} else
|
||||
count = uinput_alloc_device(file, buffer, count);
|
||||
retval = udev->state == UIST_CREATED ?
|
||||
uinput_inject_event(udev, buffer, count) :
|
||||
uinput_setup_device(udev, 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)
|
||||
@ -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;
|
||||
int retval = 0;
|
||||
|
||||
if (!test_bit(UIST_CREATED, &udev->state))
|
||||
if (udev->state != UIST_CREATED)
|
||||
return -ENODEV;
|
||||
|
||||
if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
|
||||
return -EAGAIN;
|
||||
|
||||
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)
|
||||
return retval;
|
||||
|
||||
if (!test_bit(UIST_CREATED, &udev->state))
|
||||
return -ENODEV;
|
||||
retval = down_interruptible(&udev->sem);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
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)))
|
||||
return -EFAULT;
|
||||
if (udev->state != UIST_CREATED) {
|
||||
retval = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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;
|
||||
retval += sizeof(struct input_event);
|
||||
}
|
||||
|
||||
out:
|
||||
up(&udev->sem);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -366,28 +405,30 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait)
|
||||
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))
|
||||
uinput_destroy_device(udev);
|
||||
struct uinput_device *udev = file->private_data;
|
||||
|
||||
kfree(udev->dev->name);
|
||||
kfree(udev->dev->phys);
|
||||
kfree(udev->dev);
|
||||
uinput_destroy_device(udev);
|
||||
kfree(udev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uinput_close(struct inode *inode, struct file *file)
|
||||
{
|
||||
uinput_burn_device(file->private_data);
|
||||
return 0;
|
||||
}
|
||||
#define uinput_set_bit(_arg, _bit, _max) \
|
||||
({ \
|
||||
int __ret = 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;
|
||||
void __user *p = (void __user *)arg;
|
||||
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;
|
||||
|
||||
/* device attributes can not be changed after the device is created */
|
||||
switch (cmd) {
|
||||
case UI_SET_EVBIT:
|
||||
case UI_SET_KEYBIT:
|
||||
case UI_SET_RELBIT:
|
||||
case UI_SET_ABSBIT:
|
||||
case UI_SET_MSCBIT:
|
||||
case UI_SET_LEDBIT:
|
||||
case UI_SET_SNDBIT:
|
||||
case UI_SET_FFBIT:
|
||||
case UI_SET_PHYS:
|
||||
if (test_bit(UIST_CREATED, &udev->state))
|
||||
return -EINVAL;
|
||||
retval = down_interruptible(&udev->sem);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (!udev->dev) {
|
||||
retval = uinput_allocate_device(udev);
|
||||
if (retval)
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
@ -419,74 +455,50 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
|
||||
break;
|
||||
|
||||
case UI_DEV_DESTROY:
|
||||
retval = uinput_destroy_device(udev);
|
||||
uinput_destroy_device(udev);
|
||||
break;
|
||||
|
||||
case UI_SET_EVBIT:
|
||||
if (arg > EV_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->evbit);
|
||||
retval = uinput_set_bit(arg, evbit, EV_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_KEYBIT:
|
||||
if (arg > KEY_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->keybit);
|
||||
retval = uinput_set_bit(arg, keybit, KEY_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_RELBIT:
|
||||
if (arg > REL_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->relbit);
|
||||
retval = uinput_set_bit(arg, relbit, REL_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_ABSBIT:
|
||||
if (arg > ABS_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->absbit);
|
||||
retval = uinput_set_bit(arg, absbit, ABS_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_MSCBIT:
|
||||
if (arg > MSC_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->mscbit);
|
||||
retval = uinput_set_bit(arg, mscbit, MSC_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_LEDBIT:
|
||||
if (arg > LED_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->ledbit);
|
||||
retval = uinput_set_bit(arg, ledbit, LED_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_SNDBIT:
|
||||
if (arg > SND_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->sndbit);
|
||||
retval = uinput_set_bit(arg, sndbit, SND_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_FFBIT:
|
||||
if (arg > FF_MAX) {
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
set_bit(arg, udev->dev->ffbit);
|
||||
retval = uinput_set_bit(arg, ffbit, FF_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_SWBIT:
|
||||
retval = uinput_set_bit(arg, swbit, SW_MAX);
|
||||
break;
|
||||
|
||||
case UI_SET_PHYS:
|
||||
if (udev->state == UIST_CREATED) {
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
length = strnlen_user(p, 1024);
|
||||
if (length <= 0) {
|
||||
retval = -EFAULT;
|
||||
@ -575,23 +587,26 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
|
||||
default:
|
||||
retval = -EINVAL;
|
||||
}
|
||||
|
||||
out:
|
||||
up(&udev->sem);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct file_operations uinput_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = uinput_open,
|
||||
.release = uinput_close,
|
||||
.read = uinput_read,
|
||||
.write = uinput_write,
|
||||
.poll = uinput_poll,
|
||||
.ioctl = uinput_ioctl,
|
||||
.owner = THIS_MODULE,
|
||||
.open = uinput_open,
|
||||
.release = uinput_release,
|
||||
.read = uinput_read,
|
||||
.write = uinput_write,
|
||||
.poll = uinput_poll,
|
||||
.unlocked_ioctl = uinput_ioctl,
|
||||
};
|
||||
|
||||
static struct miscdevice uinput_misc = {
|
||||
.fops = &uinput_fops,
|
||||
.minor = UINPUT_MINOR,
|
||||
.name = UINPUT_NAME,
|
||||
.fops = &uinput_fops,
|
||||
.minor = UINPUT_MINOR,
|
||||
.name = UINPUT_NAME,
|
||||
};
|
||||
|
||||
static int __init uinput_init(void)
|
||||
|
561
drivers/input/misc/wistron_btns.c
Normal file
561
drivers/input/misc/wistron_btns.c
Normal 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(®s, 0, sizeof (regs));
|
||||
regs.eax = 0x9610;
|
||||
regs.ebx = 0x061C;
|
||||
regs.ecx = 0x0000;
|
||||
call_bios(®s);
|
||||
|
||||
return regs.eax;
|
||||
}
|
||||
|
||||
static void __init bios_attach(void)
|
||||
{
|
||||
struct regs regs;
|
||||
|
||||
memset(®s, 0, sizeof (regs));
|
||||
regs.eax = 0x9610;
|
||||
regs.ebx = 0x012E;
|
||||
call_bios(®s);
|
||||
}
|
||||
|
||||
static void bios_detach(void)
|
||||
{
|
||||
struct regs regs;
|
||||
|
||||
memset(®s, 0, sizeof (regs));
|
||||
regs.eax = 0x9610;
|
||||
regs.ebx = 0x002E;
|
||||
call_bios(®s);
|
||||
}
|
||||
|
||||
static u8 __init bios_get_cmos_address(void)
|
||||
{
|
||||
struct regs regs;
|
||||
|
||||
memset(®s, 0, sizeof (regs));
|
||||
regs.eax = 0x9610;
|
||||
regs.ebx = 0x051C;
|
||||
call_bios(®s);
|
||||
|
||||
return regs.ecx;
|
||||
}
|
||||
|
||||
static u16 __init bios_get_default_setting(u8 subsys)
|
||||
{
|
||||
struct regs regs;
|
||||
|
||||
memset(®s, 0, sizeof (regs));
|
||||
regs.eax = 0x9610;
|
||||
regs.ebx = 0x0200 | subsys;
|
||||
call_bios(®s);
|
||||
|
||||
return regs.eax;
|
||||
}
|
||||
|
||||
static void bios_set_state(u8 subsys, int enable)
|
||||
{
|
||||
struct regs regs;
|
||||
|
||||
memset(®s, 0, sizeof (regs));
|
||||
regs.eax = 0x9610;
|
||||
regs.ebx = (enable ? 0x0100 : 0x0000) | subsys;
|
||||
call_bios(®s);
|
||||
}
|
||||
|
||||
/* 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);
|
@ -269,14 +269,20 @@ static struct serio_event *serio_get_event(void)
|
||||
return event;
|
||||
}
|
||||
|
||||
static void serio_handle_events(void)
|
||||
static void serio_handle_event(void)
|
||||
{
|
||||
struct serio_event *event;
|
||||
struct serio_driver *serio_drv;
|
||||
|
||||
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) {
|
||||
case SERIO_REGISTER_PORT:
|
||||
@ -368,7 +374,7 @@ static struct serio *serio_get_pending_child(struct serio *parent)
|
||||
static int serio_thread(void *nothing)
|
||||
{
|
||||
do {
|
||||
serio_handle_events();
|
||||
serio_handle_event();
|
||||
wait_event_interruptible(serio_wait,
|
||||
kthread_should_stop() || !list_empty(&serio_event_list));
|
||||
try_to_freeze();
|
||||
|
@ -110,7 +110,7 @@ config HISAX_16_3
|
||||
|
||||
config HISAX_TELESPCI
|
||||
bool "Teles PCI"
|
||||
depends on PCI && (BROKEN || !(SPARC64 || PPC))
|
||||
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
|
||||
help
|
||||
This enables HiSax support for the Teles PCI.
|
||||
See <file:Documentation/isdn/README.HiSax> on how to configure it.
|
||||
@ -238,7 +238,7 @@ config HISAX_MIC
|
||||
|
||||
config HISAX_NETJET
|
||||
bool "NETjet card"
|
||||
depends on PCI && (BROKEN || !(SPARC64 || PPC))
|
||||
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
|
||||
help
|
||||
This enables HiSax support for the NetJet from Traverse
|
||||
Technologies.
|
||||
@ -249,7 +249,7 @@ config HISAX_NETJET
|
||||
|
||||
config HISAX_NETJET_U
|
||||
bool "NETspider U card"
|
||||
depends on PCI && (BROKEN || !(SPARC64 || PPC))
|
||||
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
|
||||
help
|
||||
This enables HiSax support for the Netspider U interface ISDN card
|
||||
from Traverse Technologies.
|
||||
@ -317,7 +317,7 @@ config HISAX_GAZEL
|
||||
|
||||
config HISAX_HFC_PCI
|
||||
bool "HFC PCI-Bus cards"
|
||||
depends on PCI && (BROKEN || !(SPARC64 || PPC))
|
||||
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
|
||||
help
|
||||
This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
|
||||
|
||||
@ -344,14 +344,14 @@ config HISAX_HFC_SX
|
||||
|
||||
config HISAX_ENTERNOW_PCI
|
||||
bool "Formula-n enter:now PCI card"
|
||||
depends on PCI && (BROKEN || !(SPARC64 || PPC))
|
||||
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
|
||||
help
|
||||
This enables HiSax support for the Formula-n enter:now PCI
|
||||
ISDN card.
|
||||
|
||||
config HISAX_AMD7930
|
||||
bool "Am7930 (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && (SPARC32 || SPARC64)
|
||||
depends on EXPERIMENTAL && SPARC
|
||||
help
|
||||
This enables HiSax support for the AMD7930 chips on some SPARCs.
|
||||
This code is not finished yet.
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
config ISDN_DRV_PCBIT
|
||||
tristate "PCBIT-D support"
|
||||
depends on ISDN_I4L && ISA && (BROKEN || !PPC)
|
||||
depends on ISDN_I4L && ISA && (BROKEN || X86)
|
||||
help
|
||||
This enables support for the PCBIT ISDN-card. This card is
|
||||
manufactured in Portugal by Octal. For running this card,
|
||||
|
@ -772,7 +772,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
|
||||
input_dev->name = DRIVER_NAME " remote control";
|
||||
input_dev->phys = cinergyt2->phys;
|
||||
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);
|
||||
input_dev->keycodesize = 0;
|
||||
input_dev->keycodemax = 0;
|
||||
|
@ -673,7 +673,6 @@ static int ir_probe(struct device *dev)
|
||||
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
|
||||
pci_name(sub->core->pci));
|
||||
|
||||
ir->sub = sub;
|
||||
ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
|
||||
input_dev->name = ir->name;
|
||||
input_dev->phys = ir->phys;
|
||||
@ -688,6 +687,9 @@ static int ir_probe(struct device *dev)
|
||||
}
|
||||
input_dev->cdev.dev = &sub->core->pci->dev;
|
||||
|
||||
ir->input = input_dev;
|
||||
ir->sub = sub;
|
||||
|
||||
if (ir->polling) {
|
||||
INIT_WORK(&ir->work, ir_work, ir);
|
||||
init_timer(&ir->timer);
|
||||
@ -708,7 +710,6 @@ static int ir_probe(struct device *dev)
|
||||
/* all done */
|
||||
dev_set_drvdata(dev, ir);
|
||||
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 */
|
||||
ir->input->rep[REP_DELAY] = repeat_delay;
|
||||
|
@ -713,6 +713,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ir->dev = input_dev;
|
||||
|
||||
/* init hardware-specific stuff */
|
||||
ir->mask_keycode = mask_keycode;
|
||||
ir->mask_keydown = mask_keydown;
|
||||
|
@ -246,7 +246,7 @@ int __init ipaq_mtd_init(void)
|
||||
ipaq_map[i].size = h3xxx_max_flash_size;
|
||||
ipaq_map[i].set_vpp = h3xxx_set_vpp;
|
||||
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())
|
||||
ipaq_map[i].bankwidth = 2;
|
||||
}
|
||||
@ -280,7 +280,7 @@ int __init ipaq_mtd_init(void)
|
||||
nb_parts = ARRAY_SIZE(jornada_partitions);
|
||||
ipaq_map[0].size = jornada_max_flash_size;
|
||||
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
|
||||
#ifdef CONFIG_SA1100_JORNADA720
|
||||
@ -442,7 +442,7 @@ static int __init h1900_special_case(void)
|
||||
ipaq_map[0].size = 0x80000;
|
||||
ipaq_map[0].set_vpp = h3xxx_set_vpp;
|
||||
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;
|
||||
|
||||
printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
|
||||
|
@ -159,12 +159,12 @@ static int ixp2000_flash_probe(struct platform_device *dev)
|
||||
return -ENODEV;
|
||||
|
||||
window_size = dev->resource->end - dev->resource->start + 1;
|
||||
dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
|
||||
ixp_data->nr_banks, ((u32)window_size >> 20));
|
||||
dev_info(&dev->dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
|
||||
ixp_data->nr_banks, ((u32)window_size >> 20));
|
||||
|
||||
if (plat->width != 1) {
|
||||
dev_err(_dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
|
||||
plat->width * 8);
|
||||
dev_err(&dev->dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
|
||||
plat->width * 8);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
|
||||
dev->resource->end - dev->resource->start + 1,
|
||||
dev->dev.bus_id);
|
||||
if (!info->res) {
|
||||
dev_err(_dev, "Could not reserve memory region\n");
|
||||
dev_err(&dev->dev, "Could not reserve memory region\n");
|
||||
err = -ENOMEM;
|
||||
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,
|
||||
dev->resource->end - dev->resource->start + 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;
|
||||
goto Error;
|
||||
}
|
||||
@ -221,13 +221,13 @@ static int ixp2000_flash_probe(struct platform_device *dev)
|
||||
*/
|
||||
|
||||
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");
|
||||
#endif
|
||||
|
||||
info->mtd = do_map_probe(plat->map_name, &info->map);
|
||||
if (!info->mtd) {
|
||||
dev_err(_dev, "map_probe failed\n");
|
||||
dev_err(&dev->dev, "map_probe failed\n");
|
||||
err = -ENXIO;
|
||||
goto Error;
|
||||
}
|
||||
@ -237,7 +237,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
|
||||
if (err > 0) {
|
||||
err = add_mtd_partitions(info->mtd, info->partitions, err);
|
||||
if(err)
|
||||
dev_err(_dev, "Could not parse partitions\n");
|
||||
dev_err(&dev->dev, "Could not parse partitions\n");
|
||||
}
|
||||
|
||||
if (err)
|
||||
@ -251,8 +251,8 @@ Error:
|
||||
}
|
||||
|
||||
static struct platform_driver ixp2000_flash_driver = {
|
||||
.probe = &ixp2000_flash_probe,
|
||||
.remove = &ixp2000_flash_remove
|
||||
.probe = ixp2000_flash_probe,
|
||||
.remove = ixp2000_flash_remove,
|
||||
.driver = {
|
||||
.name = "IXP2000-Flash",
|
||||
},
|
||||
|
@ -112,7 +112,7 @@ static int __init h1910_init (void)
|
||||
if (!machine_is_h1900())
|
||||
return -ENODEV;
|
||||
|
||||
nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
|
||||
nandaddr = ioremap(0x08000000, 0x1000);
|
||||
if (!nandaddr) {
|
||||
printk("Failed to ioremap nand flash.\n");
|
||||
return -ENOMEM;
|
||||
|
@ -32,6 +32,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
|
@ -156,7 +156,7 @@
|
||||
|
||||
#define DRV_NAME "e100"
|
||||
#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_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation"
|
||||
#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)
|
||||
{
|
||||
struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
|
||||
struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
|
||||
struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
|
||||
struct param_range cbs = { .min = 64, .max = 256, .count = 128 };
|
||||
|
||||
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 */
|
||||
@ -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]);
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
/* 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)
|
||||
{
|
||||
int i;
|
||||
static const u32 ucode[UCODE_SIZE] = {
|
||||
/* NFS packets are misinterpreted as TCO packets and
|
||||
* incorrectly routed to the BMC over SMBus. This
|
||||
* microcode patch checks the fragmented IP bit in the
|
||||
* NFS/UDP header to distinguish between NFS and TCO. */
|
||||
0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
|
||||
0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
|
||||
0x00906EFD, 0x00900EFD, 0x00E00EF8,
|
||||
};
|
||||
/* *INDENT-OFF* */
|
||||
static struct {
|
||||
u32 ucode[UCODE_SIZE + 1];
|
||||
u8 mac;
|
||||
u8 timer_dword;
|
||||
u8 bundle_dword;
|
||||
u8 min_size_dword;
|
||||
} ucode_opts[] = {
|
||||
{ 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->command = cpu_to_le16(cb_ucode);
|
||||
} else
|
||||
cb->command = cpu_to_le16(cb_nop);
|
||||
return;
|
||||
}
|
||||
|
||||
noloaducode:
|
||||
cb->command = cpu_to_le16(cb_nop);
|
||||
}
|
||||
|
||||
static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
|
||||
|
@ -1,6 +1,6 @@
|
||||
config FEC_8XX
|
||||
tristate "Motorola 8xx FEC driver"
|
||||
depends on NET_ETHERNET && FEC
|
||||
depends on NET_ETHERNET && 8xx
|
||||
select MII
|
||||
|
||||
config FEC_8XX_GENERIC_PHY
|
||||
|
@ -1360,7 +1360,7 @@ static struct pci_driver ioc3_driver = {
|
||||
|
||||
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)
|
||||
|
@ -1346,10 +1346,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
|
||||
} else {
|
||||
if (netif_msg_probe(tp)) {
|
||||
printk(KERN_ERR PFX
|
||||
"Cannot find PowerManagement capability. "
|
||||
"Aborting.\n");
|
||||
"PowerManagement capability not found.\n");
|
||||
}
|
||||
goto err_out_mwi;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
if (boguscnt <= 0) {
|
||||
if (net_ratelimit() && netif_msg_intr(tp)) {
|
||||
if (netif_msg_intr(tp) && net_ratelimit() ) {
|
||||
printk(KERN_WARNING
|
||||
"%s: Too much work at interrupt!\n", dev->name);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
* Copyright (C) 2000, 2005 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. */
|
||||
#define SAA9730_LAN_REGS_ADDR 0x20400
|
||||
#define SAA9730_LAN_REGS_SIZE 0x00400
|
||||
|
||||
struct lan_saa9730_regmap {
|
||||
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. */
|
||||
#define SAA9730_EVM_REGS_ADDR 0x02000
|
||||
#define SAA9730_EVM_REGS_SIZE 0x00400
|
||||
|
||||
struct evm_saa9730_regmap {
|
||||
volatile unsigned int InterruptStatus1; /* 0x2000 */
|
||||
@ -329,16 +332,32 @@ typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
|
||||
|
||||
|
||||
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. */
|
||||
t_lan_saa9730_regmap *lan_saa9730_regs;
|
||||
|
||||
/* Pointer to the SAA9730 EVM register. */
|
||||
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. */
|
||||
unsigned char NextRcvPacketIndex;
|
||||
/* Next buffer index. */
|
||||
unsigned char NextRcvBufferIndex;
|
||||
|
||||
/* Index of next packet to use in that buffer. */
|
||||
unsigned char NextTxmPacketIndex;
|
||||
@ -353,13 +372,8 @@ struct lan_saa9730_private {
|
||||
unsigned char DmaRcvPackets;
|
||||
unsigned char DmaTxmPackets;
|
||||
|
||||
unsigned char RcvAIndex; /* index into RcvBufferSpace[] for Blk A */
|
||||
unsigned char RcvBIndex; /* index into RcvBufferSpace[] for Blk B */
|
||||
|
||||
unsigned int
|
||||
TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
|
||||
unsigned int
|
||||
RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
|
||||
void *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
|
||||
void *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
|
||||
unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
|
||||
|
||||
unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
|
||||
|
@ -154,6 +154,12 @@ MODULE_LICENSE("GPL");
|
||||
*/
|
||||
#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
|
||||
* 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 */
|
||||
SMC_SET_MMU_CMD(MC_ENQUEUE);
|
||||
SMC_ACK_INT(IM_TX_EMPTY_INT);
|
||||
smc_special_unlock(&lp->lock);
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
@ -1207,6 +1212,7 @@ static void smc_phy_configure(void *data)
|
||||
smc_phy_check_media(dev, 1);
|
||||
|
||||
smc_phy_configure_exit:
|
||||
SMC_SELECT_BANK(2);
|
||||
spin_unlock_irq(&lp->lock);
|
||||
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);
|
||||
|
||||
/* set a timeout value, so I don't stay here forever */
|
||||
timeout = 8;
|
||||
timeout = MAX_IRQ_LOOPS;
|
||||
|
||||
do {
|
||||
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 */
|
||||
SMC_SET_PTR(saved_pointer);
|
||||
SMC_SET_INT_MASK(mask);
|
||||
|
||||
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
|
||||
|
@ -192,7 +192,9 @@ static int cisco_rx(struct sk_buff *skb)
|
||||
"uptime %ud%uh%um%us)\n",
|
||||
dev->name, days, hrs,
|
||||
min, sec);
|
||||
#if 0
|
||||
netif_carrier_on(dev);
|
||||
#endif
|
||||
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.up = 0;
|
||||
printk(KERN_INFO "%s: Link down\n", dev->name);
|
||||
#if 0
|
||||
netif_carrier_off(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
del_timer_sync(&hdlc->state.cisco.timer);
|
||||
#if 0
|
||||
if (netif_carrier_ok(dev))
|
||||
netif_carrier_off(dev);
|
||||
#endif
|
||||
hdlc->state.cisco.up = 0;
|
||||
hdlc->state.cisco.request_sent = 0;
|
||||
}
|
||||
|
@ -545,8 +545,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
|
||||
|
||||
hdlc->state.fr.reliable = reliable;
|
||||
if (reliable) {
|
||||
#if 0
|
||||
if (!netif_carrier_ok(dev))
|
||||
netif_carrier_on(dev);
|
||||
#endif
|
||||
|
||||
hdlc->state.fr.n391cnt = 0; /* Request full status */
|
||||
hdlc->state.fr.dce_changed = 1;
|
||||
@ -560,8 +562,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#if 0
|
||||
if (netif_carrier_ok(dev))
|
||||
netif_carrier_off(dev);
|
||||
#endif
|
||||
|
||||
while (pvc) { /* Deactivate all PVCs */
|
||||
pvc_carrier(0, pvc);
|
||||
|
@ -79,11 +79,13 @@ static void __hdlc_set_carrier_on(struct net_device *dev)
|
||||
hdlc_device *hdlc = dev_to_hdlc(dev);
|
||||
if (hdlc->proto.start)
|
||||
return hdlc->proto.start(dev);
|
||||
#if 0
|
||||
#ifdef DEBUG_LINK
|
||||
if (netif_carrier_ok(dev))
|
||||
printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
|
||||
#endif
|
||||
netif_carrier_on(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -94,11 +96,13 @@ static void __hdlc_set_carrier_off(struct net_device *dev)
|
||||
if (hdlc->proto.stop)
|
||||
return hdlc->proto.stop(dev);
|
||||
|
||||
#if 0
|
||||
#ifdef DEBUG_LINK
|
||||
if (!netif_carrier_ok(dev))
|
||||
printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
|
||||
#endif
|
||||
netif_carrier_off(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -294,8 +298,10 @@ int register_hdlc_device(struct net_device *dev)
|
||||
if (result != 0)
|
||||
return -EIO;
|
||||
|
||||
#if 0
|
||||
if (netif_carrier_ok(dev))
|
||||
netif_carrier_off(dev); /* no carrier until DCD goes up */
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user