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

12
CREDITS
View File

@ -611,8 +611,7 @@ S: USA
N: Randolph Chung
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -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);

View File

@ -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

View File

@ -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);
}
/*

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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

View File

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

View File

@ -420,7 +420,8 @@ static void __init bootmem_init(struct meminfo *mi)
* Set up device the mappings. Since we clear out the page tables for all
* 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();
}
/*

View File

@ -130,8 +130,7 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/
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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -743,13 +743,14 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
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;

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -196,8 +196,7 @@ static int perf_open(struct inode *inode, struct file *file);
static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
static ssize_t perf_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
};

View File

@ -264,6 +264,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* sigkill. perhaps it should be put in the status
* 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:

View File

@ -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;

View File

@ -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;

View File

@ -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! */

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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");

View File

@ -361,7 +361,8 @@ static void mpic_enable_irq(unsigned int irq)
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
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));
}

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -1017,10 +1017,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
status = -ENOMEM;
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);
}
}

View File

@ -416,7 +416,7 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data
}
static struct aper_size_info_32 uli_sizes[7] =
static const struct aper_size_info_32 uli_sizes[7] =
{
{256, 65536, 6, 10},
{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 },

View File

@ -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},

View File

@ -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),
{ }
};

View File

@ -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;
}

View File

@ -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;

View File

@ -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>.

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -1629,12 +1629,6 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
* for the new rq to be completed. This is VERY DANGEROUS, and is
* 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

View File

@ -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;
}

View File

@ -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");

View File

@ -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);

View File

@ -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, &reg49h);
for (i=0;i<256;i++)
pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10);
pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10);
}
return 0;
#endif
default:
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;
}

View File

@ -876,10 +876,15 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static 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;

View File

@ -222,10 +222,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
/* We must not grab the entire device, it has 'ISA' space in its
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)) {

View File

@ -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:

View File

@ -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 },

View File

@ -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);

View File

@ -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;
}

View File

@ -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
*

View File

@ -312,7 +312,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
int ret, length, hdr_len, copy_offset;
int 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);

View File

@ -730,14 +730,15 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
}
if (attr_mask & IB_QP_ACCESS_FLAGS) {
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));
}
/*

View File

@ -802,13 +802,21 @@ static int srp_post_recv(struct srp_target_port *target)
/*
* Must be called with target->scsi_host->host_lock held to protect
* 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);

View File

@ -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,

View File

@ -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();

View File

@ -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();

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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)

View File

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

View File

@ -269,14 +269,20 @@ static struct serio_event *serio_get_event(void)
return event;
}
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();

View File

@ -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.

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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",
},

View File

@ -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;

View File

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

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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);
}

View File

@ -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];

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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