Merge branch 'from-linus' into upstream
This commit is contained in:
commit
e9ffb3d7ec
|
@ -153,10 +153,13 @@ scaling_governor, and by "echoing" the name of another
|
|||
that some governors won't load - they only
|
||||
work on some specific architectures or
|
||||
processors.
|
||||
scaling_min_freq and
|
||||
scaling_min_freq and
|
||||
scaling_max_freq show the current "policy limits" (in
|
||||
kHz). By echoing new values into these
|
||||
files, you can change these limits.
|
||||
NOTE: when setting a policy you need to
|
||||
first set scaling_max_freq, then
|
||||
scaling_min_freq.
|
||||
|
||||
|
||||
If you have selected the "userspace" governor which allows you to
|
||||
|
|
|
@ -247,7 +247,7 @@ the object-specific fields, which include:
|
|||
- default_attrs: Default attributes to be exported via sysfs when the
|
||||
object is registered.Note that the last attribute has to be
|
||||
initialized to NULL ! You can find a complete implementation
|
||||
in drivers/block/genhd.c
|
||||
in block/genhd.c
|
||||
|
||||
|
||||
Instances of struct kobj_type are not registered; only referenced by
|
||||
|
|
|
@ -211,9 +211,8 @@ Controls the kernel's behaviour when an oops or BUG is encountered.
|
|||
|
||||
0: try to continue operation
|
||||
|
||||
1: delay a few seconds (to give klogd time to record the oops output) and
|
||||
then panic. If the `panic' sysctl is also non-zero then the machine will
|
||||
be rebooted.
|
||||
1: panic immediatly. If the `panic' sysctl is also non-zero then the
|
||||
machine will be rebooted.
|
||||
|
||||
==============================================================
|
||||
|
||||
|
|
23
MAINTAINERS
23
MAINTAINERS
|
@ -298,6 +298,13 @@ L: info-linux@geode.amd.com
|
|||
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
|
||||
S: Supported
|
||||
|
||||
AOA (Apple Onboard Audio) ALSA DRIVER
|
||||
P: Johannes Berg
|
||||
M: johannes@sipsolutions.net
|
||||
L: linuxppc-dev@ozlabs.org
|
||||
L: alsa-devel@alsa-project.org
|
||||
S: Maintained
|
||||
|
||||
APM DRIVER
|
||||
P: Stephen Rothwell
|
||||
M: sfr@canb.auug.org.au
|
||||
|
@ -2653,6 +2660,22 @@ M: dbrownell@users.sourceforge.net
|
|||
L: spi-devel-general@lists.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
STABLE BRANCH:
|
||||
P: Greg Kroah-Hartman
|
||||
M: greg@kroah.com
|
||||
P: Chris Wright
|
||||
M: chrisw@sous-sol.org
|
||||
L: stable@kernel.org
|
||||
S: Maintained
|
||||
|
||||
STABLE BRANCH:
|
||||
P: Greg Kroah-Hartman
|
||||
M: greg@kroah.com
|
||||
P: Chris Wright
|
||||
M: chrisw@sous-sol.org
|
||||
L: stable@kernel.org
|
||||
S: Maintained
|
||||
|
||||
TPM DEVICE DRIVER
|
||||
P: Kylene Hall
|
||||
M: kjhall@us.ibm.com
|
||||
|
|
26
Makefile
26
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 18
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc4
|
||||
NAME=Crazed Snow-Weasel
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -436,12 +436,13 @@ core-y := usr/
|
|||
endif # KBUILD_EXTMOD
|
||||
|
||||
ifeq ($(dot-config),1)
|
||||
# In this section, we need .config
|
||||
# Read in config
|
||||
-include include/config/auto.conf
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# Read in dependencies to all Kconfig* files, make sure to run
|
||||
# oldconfig if changes are detected.
|
||||
-include include/config/auto.conf.cmd
|
||||
-include include/config/auto.conf
|
||||
|
||||
# To avoid any implicit rule to kick in, define an empty command
|
||||
$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
|
||||
|
@ -451,16 +452,27 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
|
|||
# if auto.conf.cmd is missing then we are probably in a cleaned tree so
|
||||
# we execute the config step to be sure to catch updated Kconfig files
|
||||
include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
|
||||
else
|
||||
$(error kernel configuration not valid - run 'make prepare' in $(srctree) to update it)
|
||||
endif
|
||||
# external modules needs include/linux/autoconf.h and include/config/auto.conf
|
||||
# but do not care if they are up-to-date. Use auto.conf to trigger the test
|
||||
PHONY += include/config/auto.conf
|
||||
|
||||
include/config/auto.conf:
|
||||
$(Q)test -e include/linux/autoconf.h -a -e $@ || ( \
|
||||
echo; \
|
||||
echo " ERROR: Kernel configuration is invalid."; \
|
||||
echo " include/linux/autoconf.h or $@ are missing."; \
|
||||
echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
|
||||
echo; \
|
||||
/bin/false)
|
||||
|
||||
endif # KBUILD_EXTMOD
|
||||
|
||||
else
|
||||
# Dummy target needed, because used as prerequisite
|
||||
include/config/auto.conf: ;
|
||||
endif
|
||||
endif # $(dot-config)
|
||||
|
||||
# The all: target is the default when no target is given on the
|
||||
# command line.
|
||||
|
|
|
@ -68,6 +68,7 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc
|
|||
rtc_time_to_tm(next_time, next);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtc_next_alarm_time);
|
||||
|
||||
static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm)
|
||||
{
|
||||
|
|
|
@ -532,8 +532,6 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pci_set_dma_mask);
|
||||
EXPORT_SYMBOL(pci_set_consistent_dma_mask);
|
||||
EXPORT_SYMBOL(ixp4xx_pci_read);
|
||||
EXPORT_SYMBOL(ixp4xx_pci_write);
|
||||
|
||||
|
|
|
@ -107,9 +107,9 @@ static struct flash_platform_data gtwx5715_flash_data = {
|
|||
.width = 2,
|
||||
};
|
||||
|
||||
static struct gtw5715_flash_resource = {
|
||||
static struct resource gtwx5715_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device gtwx5715_flash = {
|
||||
.name = "IXP4XX-Flash",
|
||||
|
@ -130,9 +130,6 @@ static void __init gtwx5715_init(void)
|
|||
{
|
||||
ixp4xx_sys_init();
|
||||
|
||||
if (!flash_resource)
|
||||
printk(KERN_ERR "Could not allocate flash resource\n");
|
||||
|
||||
gtwx5715_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
|
||||
gtwx5715_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1;
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ config X86_POWERNOW_K8_ACPI
|
|||
|
||||
config X86_GX_SUSPMOD
|
||||
tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
|
||||
depends on PCI
|
||||
help
|
||||
This add the CPUFreq driver for NatSemi Geode processors which
|
||||
support suspend modulation.
|
||||
|
@ -202,7 +203,7 @@ config X86_LONGRUN
|
|||
config X86_LONGHAUL
|
||||
tristate "VIA Cyrix III Longhaul"
|
||||
select CPU_FREQ_TABLE
|
||||
depends on BROKEN
|
||||
depends on ACPI_PROCESSOR
|
||||
help
|
||||
This adds the CPUFreq driver for VIA Samuel/CyrixIII,
|
||||
VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
|
||||
|
|
|
@ -384,8 +384,7 @@ static int acpi_cpufreq_early_init_acpi(void)
|
|||
}
|
||||
|
||||
/* Do initialization in ACPI core */
|
||||
acpi_processor_preregister_performance(acpi_perf_data);
|
||||
return 0;
|
||||
return acpi_processor_preregister_performance(acpi_perf_data);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
#include <linux/cpufreq.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/msr.h>
|
||||
#include <asm/timex.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/processor.h>
|
||||
|
||||
#include "longhaul.h"
|
||||
|
||||
|
@ -56,6 +58,8 @@ static int minvid, maxvid;
|
|||
static unsigned int minmult, maxmult;
|
||||
static int can_scale_voltage;
|
||||
static int vrmrev;
|
||||
static struct acpi_processor *pr = NULL;
|
||||
static struct acpi_processor_cx *cx = NULL;
|
||||
|
||||
/* Module parameters */
|
||||
static int dont_scale_voltage;
|
||||
|
@ -118,84 +122,65 @@ static int longhaul_get_cpu_mult(void)
|
|||
return eblcr_table[invalue];
|
||||
}
|
||||
|
||||
/* For processor with BCR2 MSR */
|
||||
|
||||
static void do_powersaver(union msr_longhaul *longhaul,
|
||||
unsigned int clock_ratio_index)
|
||||
static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
unsigned long flags;
|
||||
unsigned int tmp_mask;
|
||||
int version;
|
||||
int i;
|
||||
u16 pci_cmd;
|
||||
u16 cmd_state[64];
|
||||
union msr_bcr2 bcr2;
|
||||
u32 t;
|
||||
|
||||
switch (cpu_model) {
|
||||
case CPU_EZRA_T:
|
||||
version = 3;
|
||||
break;
|
||||
case CPU_NEHEMIAH:
|
||||
version = 0xf;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
|
||||
longhaul->bits.SoftBusRatio = clock_ratio_index & 0xf;
|
||||
longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
|
||||
longhaul->bits.EnableSoftBusRatio = 1;
|
||||
longhaul->bits.RevisionKey = 0;
|
||||
|
||||
preempt_disable();
|
||||
local_irq_save(flags);
|
||||
|
||||
/*
|
||||
* get current pci bus master state for all devices
|
||||
* and clear bus master bit
|
||||
*/
|
||||
dev = NULL;
|
||||
i = 0;
|
||||
do {
|
||||
dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
|
||||
if (dev != NULL) {
|
||||
pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
|
||||
cmd_state[i++] = pci_cmd;
|
||||
pci_cmd &= ~PCI_COMMAND_MASTER;
|
||||
pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
|
||||
}
|
||||
} while (dev != NULL);
|
||||
|
||||
tmp_mask=inb(0x21); /* works on C3. save mask. */
|
||||
outb(0xFE,0x21); /* TMR0 only */
|
||||
outb(0xFF,0x80); /* delay */
|
||||
rdmsrl(MSR_VIA_BCR2, bcr2.val);
|
||||
/* Enable software clock multiplier */
|
||||
bcr2.bits.ESOFTBF = 1;
|
||||
bcr2.bits.CLOCKMUL = clock_ratio_index;
|
||||
|
||||
/* Sync to timer tick */
|
||||
safe_halt();
|
||||
wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
|
||||
halt();
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
/* Change frequency on next halt or sleep */
|
||||
wrmsrl(MSR_VIA_BCR2, bcr2.val);
|
||||
/* Invoke C3 */
|
||||
inb(cx_address);
|
||||
/* Dummy op - must do something useless after P_LVL3 read */
|
||||
t = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
|
||||
/* Disable software clock multiplier */
|
||||
local_irq_disable();
|
||||
rdmsrl(MSR_VIA_BCR2, bcr2.val);
|
||||
bcr2.bits.ESOFTBF = 0;
|
||||
wrmsrl(MSR_VIA_BCR2, bcr2.val);
|
||||
}
|
||||
|
||||
outb(tmp_mask,0x21); /* restore mask */
|
||||
/* For processor with Longhaul MSR */
|
||||
|
||||
/* restore pci bus master state for all devices */
|
||||
dev = NULL;
|
||||
i = 0;
|
||||
do {
|
||||
dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
|
||||
if (dev != NULL) {
|
||||
pci_cmd = cmd_state[i++];
|
||||
pci_write_config_byte(dev, PCI_COMMAND, pci_cmd);
|
||||
}
|
||||
} while (dev != NULL);
|
||||
local_irq_restore(flags);
|
||||
preempt_enable();
|
||||
static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
|
||||
{
|
||||
union msr_longhaul longhaul;
|
||||
u32 t;
|
||||
|
||||
/* disable bus ratio bit */
|
||||
rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
|
||||
longhaul->bits.EnableSoftBusRatio = 0;
|
||||
longhaul->bits.RevisionKey = version;
|
||||
wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
|
||||
rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
|
||||
longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
|
||||
longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
|
||||
longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
|
||||
longhaul.bits.EnableSoftBusRatio = 1;
|
||||
|
||||
/* Sync to timer tick */
|
||||
safe_halt();
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
/* Change frequency on next halt or sleep */
|
||||
wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
|
||||
/* Invoke C3 */
|
||||
inb(cx_address);
|
||||
/* Dummy op - must do something useless after P_LVL3 read */
|
||||
t = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
|
||||
/* Disable bus ratio bit */
|
||||
local_irq_disable();
|
||||
longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
|
||||
longhaul.bits.EnableSoftBusRatio = 0;
|
||||
longhaul.bits.EnableSoftBSEL = 0;
|
||||
longhaul.bits.EnableSoftVID = 0;
|
||||
wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,9 +194,9 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
|
|||
{
|
||||
int speed, mult;
|
||||
struct cpufreq_freqs freqs;
|
||||
union msr_longhaul longhaul;
|
||||
union msr_bcr2 bcr2;
|
||||
static unsigned int old_ratio=-1;
|
||||
unsigned long flags;
|
||||
unsigned int pic1_mask, pic2_mask;
|
||||
|
||||
if (old_ratio == clock_ratio_index)
|
||||
return;
|
||||
|
@ -234,6 +219,20 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
|
|||
dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
|
||||
fsb, mult/10, mult%10, print_speed(speed/1000));
|
||||
|
||||
preempt_disable();
|
||||
local_irq_save(flags);
|
||||
|
||||
pic2_mask = inb(0xA1);
|
||||
pic1_mask = inb(0x21); /* works on C3. save mask. */
|
||||
outb(0xFF,0xA1); /* Overkill */
|
||||
outb(0xFE,0x21); /* TMR0 only */
|
||||
|
||||
/* Disable bus master arbitration */
|
||||
if (pr->flags.bm_check) {
|
||||
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
|
||||
ACPI_MTX_DO_NOT_LOCK);
|
||||
}
|
||||
|
||||
switch (longhaul_version) {
|
||||
|
||||
/*
|
||||
|
@ -245,20 +244,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
|
|||
*/
|
||||
case TYPE_LONGHAUL_V1:
|
||||
case TYPE_LONGHAUL_V2:
|
||||
rdmsrl (MSR_VIA_BCR2, bcr2.val);
|
||||
/* Enable software clock multiplier */
|
||||
bcr2.bits.ESOFTBF = 1;
|
||||
bcr2.bits.CLOCKMUL = clock_ratio_index;
|
||||
local_irq_disable();
|
||||
wrmsrl (MSR_VIA_BCR2, bcr2.val);
|
||||
safe_halt();
|
||||
|
||||
/* Disable software clock multiplier */
|
||||
rdmsrl (MSR_VIA_BCR2, bcr2.val);
|
||||
bcr2.bits.ESOFTBF = 0;
|
||||
local_irq_disable();
|
||||
wrmsrl (MSR_VIA_BCR2, bcr2.val);
|
||||
local_irq_enable();
|
||||
do_longhaul1(cx->address, clock_ratio_index);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -273,10 +259,22 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
|
|||
* to work in practice.
|
||||
*/
|
||||
case TYPE_POWERSAVER:
|
||||
do_powersaver(&longhaul, clock_ratio_index);
|
||||
do_powersaver(cx->address, clock_ratio_index);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable bus master arbitration */
|
||||
if (pr->flags.bm_check) {
|
||||
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
|
||||
ACPI_MTX_DO_NOT_LOCK);
|
||||
}
|
||||
|
||||
outb(pic2_mask,0xA1); /* restore mask */
|
||||
outb(pic1_mask,0x21);
|
||||
|
||||
local_irq_restore(flags);
|
||||
preempt_enable();
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
}
|
||||
|
||||
|
@ -324,9 +322,11 @@ static int guess_fsb(void)
|
|||
static int __init longhaul_get_ranges(void)
|
||||
{
|
||||
unsigned long invalue;
|
||||
unsigned int multipliers[32]= {
|
||||
50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
|
||||
-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
|
||||
unsigned int ezra_t_multipliers[32]= {
|
||||
90, 30, 40, 100, 55, 35, 45, 95,
|
||||
50, 70, 80, 60, 120, 75, 85, 65,
|
||||
-1, 110, 120, -1, 135, 115, 125, 105,
|
||||
130, 150, 160, 140, -1, 155, -1, 145 };
|
||||
unsigned int j, k = 0;
|
||||
union msr_longhaul longhaul;
|
||||
unsigned long lo, hi;
|
||||
|
@ -355,13 +355,13 @@ static int __init longhaul_get_ranges(void)
|
|||
invalue = longhaul.bits.MaxMHzBR;
|
||||
if (longhaul.bits.MaxMHzBR4)
|
||||
invalue += 16;
|
||||
maxmult=multipliers[invalue];
|
||||
maxmult=ezra_t_multipliers[invalue];
|
||||
|
||||
invalue = longhaul.bits.MinMHzBR;
|
||||
if (longhaul.bits.MinMHzBR4 == 1)
|
||||
minmult = 30;
|
||||
else
|
||||
minmult = multipliers[invalue];
|
||||
minmult = ezra_t_multipliers[invalue];
|
||||
fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
|
||||
break;
|
||||
}
|
||||
|
@ -527,6 +527,18 @@ static unsigned int longhaul_get(unsigned int cpu)
|
|||
return calc_speed(longhaul_get_cpu_mult());
|
||||
}
|
||||
|
||||
static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
|
||||
u32 nesting_level,
|
||||
void *context, void **return_value)
|
||||
{
|
||||
struct acpi_device *d;
|
||||
|
||||
if ( acpi_bus_get_device(obj_handle, &d) ) {
|
||||
return 0;
|
||||
}
|
||||
*return_value = (void *)acpi_driver_data(d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
|
@ -534,6 +546,15 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
|
|||
char *cpuname=NULL;
|
||||
int ret;
|
||||
|
||||
/* Check ACPI support for C3 state */
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
|
||||
&longhaul_walk_callback, NULL, (void *)&pr);
|
||||
if (pr == NULL) goto err_acpi;
|
||||
|
||||
cx = &pr->power.states[ACPI_STATE_C3];
|
||||
if (cx->address == 0 || cx->latency > 1000) goto err_acpi;
|
||||
|
||||
/* Now check what we have on this motherboard */
|
||||
switch (c->x86_model) {
|
||||
case 6:
|
||||
cpu_model = CPU_SAMUEL;
|
||||
|
@ -634,6 +655,10 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
|
|||
cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu);
|
||||
|
||||
return 0;
|
||||
|
||||
err_acpi:
|
||||
printk(KERN_ERR PFX "No ACPI support for CPU frequency changes.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy)
|
||||
|
@ -666,6 +691,18 @@ static int __init longhaul_init(void)
|
|||
if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
|
||||
return -ENODEV;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (num_online_cpus() > 1) {
|
||||
return -ENODEV;
|
||||
printk(KERN_ERR PFX "More than 1 CPU detected, longhaul disabled.\n");
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
if (cpu_has_apic) {
|
||||
printk(KERN_ERR PFX "APIC detected. Longhaul is currently broken in this configuration.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
switch (c->x86_model) {
|
||||
case 6 ... 9:
|
||||
return cpufreq_register_driver(&longhaul_driver);
|
||||
|
@ -699,6 +736,6 @@ MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
|
|||
MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
|
||||
MODULE_LICENSE ("GPL");
|
||||
|
||||
module_init(longhaul_init);
|
||||
late_initcall(longhaul_init);
|
||||
module_exit(longhaul_exit);
|
||||
|
||||
|
|
|
@ -32,32 +32,38 @@
|
|||
|
||||
extern void __init efi_memmap_walk_uc(efi_freemem_callback_t, void *);
|
||||
|
||||
#define MAX_UNCACHED_GRANULES 5
|
||||
static int allocated_granules;
|
||||
struct uncached_pool {
|
||||
struct gen_pool *pool;
|
||||
struct mutex add_chunk_mutex; /* serialize adding a converted chunk */
|
||||
int nchunks_added; /* #of converted chunks added to pool */
|
||||
atomic_t status; /* smp called function's return status*/
|
||||
};
|
||||
|
||||
struct gen_pool *uncached_pool[MAX_NUMNODES];
|
||||
#define MAX_CONVERTED_CHUNKS_PER_NODE 2
|
||||
|
||||
struct uncached_pool uncached_pools[MAX_NUMNODES];
|
||||
|
||||
|
||||
static void uncached_ipi_visibility(void *data)
|
||||
{
|
||||
int status;
|
||||
struct uncached_pool *uc_pool = (struct uncached_pool *)data;
|
||||
|
||||
status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL);
|
||||
if ((status != PAL_VISIBILITY_OK) &&
|
||||
(status != PAL_VISIBILITY_OK_REMOTE_NEEDED))
|
||||
printk(KERN_DEBUG "pal_prefetch_visibility() returns %i on "
|
||||
"CPU %i\n", status, raw_smp_processor_id());
|
||||
atomic_inc(&uc_pool->status);
|
||||
}
|
||||
|
||||
|
||||
static void uncached_ipi_mc_drain(void *data)
|
||||
{
|
||||
int status;
|
||||
struct uncached_pool *uc_pool = (struct uncached_pool *)data;
|
||||
|
||||
status = ia64_pal_mc_drain();
|
||||
if (status)
|
||||
printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on "
|
||||
"CPU %i\n", status, raw_smp_processor_id());
|
||||
if (status != PAL_STATUS_SUCCESS)
|
||||
atomic_inc(&uc_pool->status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,21 +76,34 @@ static void uncached_ipi_mc_drain(void *data)
|
|||
* This is accomplished by first allocating a granule of cached memory pages
|
||||
* and then converting them to uncached memory pages.
|
||||
*/
|
||||
static int uncached_add_chunk(struct gen_pool *pool, int nid)
|
||||
static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid)
|
||||
{
|
||||
struct page *page;
|
||||
int status, i;
|
||||
int status, i, nchunks_added = uc_pool->nchunks_added;
|
||||
unsigned long c_addr, uc_addr;
|
||||
|
||||
if (allocated_granules >= MAX_UNCACHED_GRANULES)
|
||||
if (mutex_lock_interruptible(&uc_pool->add_chunk_mutex) != 0)
|
||||
return -1; /* interrupted by a signal */
|
||||
|
||||
if (uc_pool->nchunks_added > nchunks_added) {
|
||||
/* someone added a new chunk while we were waiting */
|
||||
mutex_unlock(&uc_pool->add_chunk_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uc_pool->nchunks_added >= MAX_CONVERTED_CHUNKS_PER_NODE) {
|
||||
mutex_unlock(&uc_pool->add_chunk_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* attempt to allocate a granule's worth of cached memory pages */
|
||||
|
||||
page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO,
|
||||
IA64_GRANULE_SHIFT-PAGE_SHIFT);
|
||||
if (!page)
|
||||
if (!page) {
|
||||
mutex_unlock(&uc_pool->add_chunk_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* convert the memory pages from cached to uncached */
|
||||
|
||||
|
@ -102,11 +121,14 @@ static int uncached_add_chunk(struct gen_pool *pool, int nid)
|
|||
flush_tlb_kernel_range(uc_addr, uc_adddr + IA64_GRANULE_SIZE);
|
||||
|
||||
status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL);
|
||||
if (!status) {
|
||||
status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1);
|
||||
if (status)
|
||||
if (status == PAL_VISIBILITY_OK_REMOTE_NEEDED) {
|
||||
atomic_set(&uc_pool->status, 0);
|
||||
status = smp_call_function(uncached_ipi_visibility, uc_pool,
|
||||
0, 1);
|
||||
if (status || atomic_read(&uc_pool->status))
|
||||
goto failed;
|
||||
}
|
||||
} else if (status != PAL_VISIBILITY_OK)
|
||||
goto failed;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
|
@ -120,20 +142,24 @@ static int uncached_add_chunk(struct gen_pool *pool, int nid)
|
|||
|
||||
preempt_enable();
|
||||
|
||||
ia64_pal_mc_drain();
|
||||
status = smp_call_function(uncached_ipi_mc_drain, NULL, 0, 1);
|
||||
if (status)
|
||||
status = ia64_pal_mc_drain();
|
||||
if (status != PAL_STATUS_SUCCESS)
|
||||
goto failed;
|
||||
atomic_set(&uc_pool->status, 0);
|
||||
status = smp_call_function(uncached_ipi_mc_drain, uc_pool, 0, 1);
|
||||
if (status || atomic_read(&uc_pool->status))
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
* The chunk of memory pages has been converted to uncached so now we
|
||||
* can add it to the pool.
|
||||
*/
|
||||
status = gen_pool_add(pool, uc_addr, IA64_GRANULE_SIZE, nid);
|
||||
status = gen_pool_add(uc_pool->pool, uc_addr, IA64_GRANULE_SIZE, nid);
|
||||
if (status)
|
||||
goto failed;
|
||||
|
||||
allocated_granules++;
|
||||
uc_pool->nchunks_added++;
|
||||
mutex_unlock(&uc_pool->add_chunk_mutex);
|
||||
return 0;
|
||||
|
||||
/* failed to convert or add the chunk so give it back to the kernel */
|
||||
|
@ -142,6 +168,7 @@ failed:
|
|||
ClearPageUncached(&page[i]);
|
||||
|
||||
free_pages(c_addr, IA64_GRANULE_SHIFT-PAGE_SHIFT);
|
||||
mutex_unlock(&uc_pool->add_chunk_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -158,7 +185,7 @@ failed:
|
|||
unsigned long uncached_alloc_page(int starting_nid)
|
||||
{
|
||||
unsigned long uc_addr;
|
||||
struct gen_pool *pool;
|
||||
struct uncached_pool *uc_pool;
|
||||
int nid;
|
||||
|
||||
if (unlikely(starting_nid >= MAX_NUMNODES))
|
||||
|
@ -171,14 +198,14 @@ unsigned long uncached_alloc_page(int starting_nid)
|
|||
do {
|
||||
if (!node_online(nid))
|
||||
continue;
|
||||
pool = uncached_pool[nid];
|
||||
if (pool == NULL)
|
||||
uc_pool = &uncached_pools[nid];
|
||||
if (uc_pool->pool == NULL)
|
||||
continue;
|
||||
do {
|
||||
uc_addr = gen_pool_alloc(pool, PAGE_SIZE);
|
||||
uc_addr = gen_pool_alloc(uc_pool->pool, PAGE_SIZE);
|
||||
if (uc_addr != 0)
|
||||
return uc_addr;
|
||||
} while (uncached_add_chunk(pool, nid) == 0);
|
||||
} while (uncached_add_chunk(uc_pool, nid) == 0);
|
||||
|
||||
} while ((nid = (nid + 1) % MAX_NUMNODES) != starting_nid);
|
||||
|
||||
|
@ -197,7 +224,7 @@ EXPORT_SYMBOL(uncached_alloc_page);
|
|||
void uncached_free_page(unsigned long uc_addr)
|
||||
{
|
||||
int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET);
|
||||
struct gen_pool *pool = uncached_pool[nid];
|
||||
struct gen_pool *pool = uncached_pools[nid].pool;
|
||||
|
||||
if (unlikely(pool == NULL))
|
||||
return;
|
||||
|
@ -224,7 +251,7 @@ static int __init uncached_build_memmap(unsigned long uc_start,
|
|||
unsigned long uc_end, void *arg)
|
||||
{
|
||||
int nid = paddr_to_nid(uc_start - __IA64_UNCACHED_OFFSET);
|
||||
struct gen_pool *pool = uncached_pool[nid];
|
||||
struct gen_pool *pool = uncached_pools[nid].pool;
|
||||
size_t size = uc_end - uc_start;
|
||||
|
||||
touch_softlockup_watchdog();
|
||||
|
@ -242,7 +269,8 @@ static int __init uncached_init(void)
|
|||
int nid;
|
||||
|
||||
for_each_online_node(nid) {
|
||||
uncached_pool[nid] = gen_pool_create(PAGE_SHIFT, nid);
|
||||
uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid);
|
||||
mutex_init(&uncached_pools[nid].add_chunk_mutex);
|
||||
}
|
||||
|
||||
efi_memmap_walk_uc(uncached_build_memmap, NULL);
|
||||
|
|
|
@ -421,18 +421,22 @@ static struct miscdevice sq_dev = {
|
|||
|
||||
static int __init sq_api_init(void)
|
||||
{
|
||||
int ret;
|
||||
printk(KERN_NOTICE "sq: Registering store queue API.\n");
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
create_proc_read_entry("sq_mapping", 0, 0, sq_mapping_read_proc, 0);
|
||||
#endif
|
||||
|
||||
return misc_register(&sq_dev);
|
||||
ret = misc_register(&sq_dev);
|
||||
if (ret)
|
||||
remove_proc_entry("sq_mapping", NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit sq_api_exit(void)
|
||||
{
|
||||
misc_deregister(&sq_dev);
|
||||
remove_proc_entry("sq_mapping", NULL);
|
||||
}
|
||||
|
||||
module_init(sq_api_init);
|
||||
|
|
|
@ -203,7 +203,7 @@ int __cpuinit init_smp_flush(void)
|
|||
{
|
||||
int i;
|
||||
for_each_cpu_mask(i, cpu_possible_map) {
|
||||
spin_lock_init(&per_cpu(flush_state.tlbstate_lock, i));
|
||||
spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -129,11 +129,15 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
|
|||
struct acpi_memory_info *info, *n;
|
||||
|
||||
|
||||
if (!list_empty(&mem_device->res_list))
|
||||
return 0;
|
||||
|
||||
status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS,
|
||||
acpi_memory_get_resource, mem_device);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
list_for_each_entry_safe(info, n, &mem_device->res_list, list)
|
||||
kfree(info);
|
||||
INIT_LIST_HEAD(&mem_device->res_list);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -230,17 +234,10 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
|||
* (i.e. memory-hot-remove function)
|
||||
*/
|
||||
list_for_each_entry(info, &mem_device->res_list, list) {
|
||||
u64 start_pfn, end_pfn;
|
||||
|
||||
start_pfn = info->start_addr >> PAGE_SHIFT;
|
||||
end_pfn = (info->start_addr + info->length - 1) >> PAGE_SHIFT;
|
||||
|
||||
if (pfn_valid(start_pfn) || pfn_valid(end_pfn)) {
|
||||
/* already enabled. try next area */
|
||||
if (info->enabled) { /* just sanity check...*/
|
||||
num_enabled++;
|
||||
continue;
|
||||
}
|
||||
|
||||
result = add_memory(node, info->start_addr, info->length);
|
||||
if (result)
|
||||
continue;
|
||||
|
|
|
@ -311,7 +311,8 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
|
|||
/* CD went away; no more connection */
|
||||
pr_debug("hvsi%i: CD dropped\n", hp->index);
|
||||
hp->mctrl &= TIOCM_CD;
|
||||
if (!(hp->tty->flags & CLOCAL))
|
||||
/* If userland hasn't done an open(2) yet, hp->tty is NULL. */
|
||||
if (hp->tty && !(hp->tty->flags & CLOCAL))
|
||||
*to_hangup = hp->tty;
|
||||
}
|
||||
break;
|
||||
|
@ -986,10 +987,7 @@ static void hvsi_write_worker(void *arg)
|
|||
start_j = 0;
|
||||
#endif /* DEBUG */
|
||||
wake_up_all(&hp->emptyq);
|
||||
if (test_bit(TTY_DO_WRITE_WAKEUP, &hp->tty->flags)
|
||||
&& hp->tty->ldisc.write_wakeup)
|
||||
hp->tty->ldisc.write_wakeup(hp->tty);
|
||||
wake_up_interruptible(&hp->tty->write_wait);
|
||||
tty_wakeup(hp->tty);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hw_random.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware/clock.h>
|
||||
|
||||
#define RNG_OUT_REG 0x00 /* Output register */
|
||||
#define RNG_STAT_REG 0x04 /* Status register
|
||||
|
@ -52,7 +52,7 @@
|
|||
|
||||
static void __iomem *rng_base;
|
||||
static struct clk *rng_ick;
|
||||
static struct device *rng_dev;
|
||||
static struct platform_device *rng_dev;
|
||||
|
||||
static u32 omap_rng_read_reg(int reg)
|
||||
{
|
||||
|
@ -83,9 +83,8 @@ static struct hwrng omap_rng_ops = {
|
|||
.data_read = omap_rng_data_read,
|
||||
};
|
||||
|
||||
static int __init omap_rng_probe(struct device *dev)
|
||||
static int __init omap_rng_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct resource *res, *mem;
|
||||
int ret;
|
||||
|
||||
|
@ -95,16 +94,14 @@ static int __init omap_rng_probe(struct device *dev)
|
|||
*/
|
||||
BUG_ON(rng_dev);
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (cpu_is_omap24xx()) {
|
||||
rng_ick = clk_get(NULL, "rng_ick");
|
||||
if (IS_ERR(rng_ick)) {
|
||||
dev_err(dev, "Could not get rng_ick\n");
|
||||
dev_err(&pdev->dev, "Could not get rng_ick\n");
|
||||
ret = PTR_ERR(rng_ick);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
clk_use(rng_ick);
|
||||
}
|
||||
} else
|
||||
clk_enable(rng_ick);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
@ -117,7 +114,7 @@ static int __init omap_rng_probe(struct device *dev)
|
|||
if (mem == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
dev_set_drvdata(dev, mem);
|
||||
dev_set_drvdata(&pdev->dev, mem);
|
||||
rng_base = (u32 __iomem *)io_p2v(res->start);
|
||||
|
||||
ret = hwrng_register(&omap_rng_ops);
|
||||
|
@ -127,25 +124,25 @@ static int __init omap_rng_probe(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
dev_info(dev, "OMAP Random Number Generator ver. %02x\n",
|
||||
dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
|
||||
omap_rng_read_reg(RNG_REV_REG));
|
||||
omap_rng_write_reg(RNG_MASK_REG, 0x1);
|
||||
|
||||
rng_dev = dev;
|
||||
rng_dev = pdev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit omap_rng_remove(struct device *dev)
|
||||
static int __exit omap_rng_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *mem = dev_get_drvdata(dev);
|
||||
struct resource *mem = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
hwrng_unregister(&omap_rng_ops);
|
||||
|
||||
omap_rng_write_reg(RNG_MASK_REG, 0x0);
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
clk_unuse(rng_ick);
|
||||
clk_disable(rng_ick);
|
||||
clk_put(rng_ick);
|
||||
}
|
||||
|
||||
|
@ -157,18 +154,16 @@ static int __exit omap_rng_remove(struct device *dev)
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int omap_rng_suspend(struct device *dev, pm_message_t message, u32 level)
|
||||
static int omap_rng_suspend(struct platform_device *pdev, pm_message_t message)
|
||||
{
|
||||
omap_rng_write_reg(RNG_MASK_REG, 0x0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_rng_resume(struct device *dev, pm_message_t message, u32 level)
|
||||
static int omap_rng_resume(struct platform_device *pdev)
|
||||
{
|
||||
omap_rng_write_reg(RNG_MASK_REG, 0x1);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -179,9 +174,11 @@ static int omap_rng_resume(struct device *dev, pm_message_t message, u32 level)
|
|||
#endif
|
||||
|
||||
|
||||
static struct device_driver omap_rng_driver = {
|
||||
.name = "omap_rng",
|
||||
.bus = &platform_bus_type,
|
||||
static struct platform_driver omap_rng_driver = {
|
||||
.driver = {
|
||||
.name = "omap_rng",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = omap_rng_probe,
|
||||
.remove = __exit_p(omap_rng_remove),
|
||||
.suspend = omap_rng_suspend,
|
||||
|
@ -193,12 +190,12 @@ static int __init omap_rng_init(void)
|
|||
if (!cpu_is_omap16xx() && !cpu_is_omap24xx())
|
||||
return -ENODEV;
|
||||
|
||||
return driver_register(&omap_rng_driver);
|
||||
return platform_driver_register(&omap_rng_driver);
|
||||
}
|
||||
|
||||
static void __exit omap_rng_exit(void)
|
||||
{
|
||||
driver_unregister(&omap_rng_driver);
|
||||
platform_driver_unregister(&omap_rng_driver);
|
||||
}
|
||||
|
||||
module_init(omap_rng_init);
|
||||
|
|
|
@ -107,7 +107,6 @@ const int NR_TYPES = ARRAY_SIZE(max_vals);
|
|||
|
||||
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
|
||||
static struct kbd_struct *kbd = kbd_table;
|
||||
static struct kbd_struct kbd0;
|
||||
|
||||
int spawnpid, spawnsig;
|
||||
|
||||
|
@ -223,13 +222,13 @@ static void kd_nosound(unsigned long ignored)
|
|||
{
|
||||
struct list_head *node;
|
||||
|
||||
list_for_each(node,&kbd_handler.h_list) {
|
||||
list_for_each(node, &kbd_handler.h_list) {
|
||||
struct input_handle *handle = to_handle_h(node);
|
||||
if (test_bit(EV_SND, handle->dev->evbit)) {
|
||||
if (test_bit(SND_TONE, handle->dev->sndbit))
|
||||
input_event(handle->dev, EV_SND, SND_TONE, 0);
|
||||
input_inject_event(handle, EV_SND, SND_TONE, 0);
|
||||
if (test_bit(SND_BELL, handle->dev->sndbit))
|
||||
input_event(handle->dev, EV_SND, SND_BELL, 0);
|
||||
input_inject_event(handle, EV_SND, SND_BELL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,11 +246,11 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
|
|||
struct input_handle *handle = to_handle_h(node);
|
||||
if (test_bit(EV_SND, handle->dev->evbit)) {
|
||||
if (test_bit(SND_TONE, handle->dev->sndbit)) {
|
||||
input_event(handle->dev, EV_SND, SND_TONE, hz);
|
||||
input_inject_event(handle, EV_SND, SND_TONE, hz);
|
||||
break;
|
||||
}
|
||||
if (test_bit(SND_BELL, handle->dev->sndbit)) {
|
||||
input_event(handle->dev, EV_SND, SND_BELL, 1);
|
||||
input_inject_event(handle, EV_SND, SND_BELL, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -272,15 +271,15 @@ int kbd_rate(struct kbd_repeat *rep)
|
|||
unsigned int d = 0;
|
||||
unsigned int p = 0;
|
||||
|
||||
list_for_each(node,&kbd_handler.h_list) {
|
||||
list_for_each(node, &kbd_handler.h_list) {
|
||||
struct input_handle *handle = to_handle_h(node);
|
||||
struct input_dev *dev = handle->dev;
|
||||
|
||||
if (test_bit(EV_REP, dev->evbit)) {
|
||||
if (rep->delay > 0)
|
||||
input_event(dev, EV_REP, REP_DELAY, rep->delay);
|
||||
input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
|
||||
if (rep->period > 0)
|
||||
input_event(dev, EV_REP, REP_PERIOD, rep->period);
|
||||
input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
|
||||
d = dev->rep[REP_DELAY];
|
||||
p = dev->rep[REP_PERIOD];
|
||||
}
|
||||
|
@ -988,7 +987,7 @@ static inline unsigned char getleds(void)
|
|||
* interrupt routines for this thing allows us to easily mask
|
||||
* this when we don't want any of the above to happen.
|
||||
* This allows for easy and efficient race-condition prevention
|
||||
* for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ...
|
||||
* for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
|
||||
*/
|
||||
|
||||
static void kbd_bh(unsigned long dummy)
|
||||
|
@ -998,11 +997,11 @@ static void kbd_bh(unsigned long dummy)
|
|||
|
||||
if (leds != ledstate) {
|
||||
list_for_each(node, &kbd_handler.h_list) {
|
||||
struct input_handle * handle = to_handle_h(node);
|
||||
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
|
||||
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
|
||||
input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04));
|
||||
input_sync(handle->dev);
|
||||
struct input_handle *handle = to_handle_h(node);
|
||||
input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
|
||||
input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
|
||||
input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
|
||||
input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1011,23 +1010,6 @@ static void kbd_bh(unsigned long dummy)
|
|||
|
||||
DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
|
||||
|
||||
/*
|
||||
* This allows a newly plugged keyboard to pick the LED state.
|
||||
*/
|
||||
static void kbd_refresh_leds(struct input_handle *handle)
|
||||
{
|
||||
unsigned char leds = ledstate;
|
||||
|
||||
tasklet_disable(&keyboard_tasklet);
|
||||
if (leds != 0xff) {
|
||||
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
|
||||
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
|
||||
input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04));
|
||||
input_sync(handle->dev);
|
||||
}
|
||||
tasklet_enable(&keyboard_tasklet);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
|
||||
defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
|
||||
defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
|
||||
|
@ -1043,7 +1025,7 @@ static const unsigned short x86_keycodes[256] =
|
|||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
|
||||
284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339,
|
||||
284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
|
||||
367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
|
||||
360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
|
||||
103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361,
|
||||
|
@ -1065,38 +1047,55 @@ extern void sun_do_break(void);
|
|||
static int emulate_raw(struct vc_data *vc, unsigned int keycode,
|
||||
unsigned char up_flag)
|
||||
{
|
||||
if (keycode > 255 || !x86_keycodes[keycode])
|
||||
return -1;
|
||||
int code;
|
||||
|
||||
switch (keycode) {
|
||||
case KEY_PAUSE:
|
||||
put_queue(vc, 0xe1);
|
||||
put_queue(vc, 0x1d | up_flag);
|
||||
put_queue(vc, 0x45 | up_flag);
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case KEY_HANGEUL:
|
||||
if (!up_flag)
|
||||
put_queue(vc, 0xf2);
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case KEY_HANJA:
|
||||
if (!up_flag)
|
||||
put_queue(vc, 0xf1);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
if (keycode == KEY_SYSRQ && sysrq_alt) {
|
||||
put_queue(vc, 0x54 | up_flag);
|
||||
return 0;
|
||||
}
|
||||
case KEY_SYSRQ:
|
||||
/*
|
||||
* Real AT keyboards (that's what we're trying
|
||||
* to emulate here emit 0xe0 0x2a 0xe0 0x37 when
|
||||
* pressing PrtSc/SysRq alone, but simply 0x54
|
||||
* when pressing Alt+PrtSc/SysRq.
|
||||
*/
|
||||
if (sysrq_alt) {
|
||||
put_queue(vc, 0x54 | up_flag);
|
||||
} else {
|
||||
put_queue(vc, 0xe0);
|
||||
put_queue(vc, 0x2a | up_flag);
|
||||
put_queue(vc, 0xe0);
|
||||
put_queue(vc, 0x37 | up_flag);
|
||||
}
|
||||
break;
|
||||
|
||||
if (x86_keycodes[keycode] & 0x100)
|
||||
put_queue(vc, 0xe0);
|
||||
default:
|
||||
if (keycode > 255)
|
||||
return -1;
|
||||
|
||||
put_queue(vc, (x86_keycodes[keycode] & 0x7f) | up_flag);
|
||||
code = x86_keycodes[keycode];
|
||||
if (!code)
|
||||
return -1;
|
||||
|
||||
if (keycode == KEY_SYSRQ) {
|
||||
put_queue(vc, 0xe0);
|
||||
put_queue(vc, 0x37 | up_flag);
|
||||
if (code & 0x100)
|
||||
put_queue(vc, 0xe0);
|
||||
put_queue(vc, (code & 0x7f) | up_flag);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1298,16 +1297,15 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
|
|||
if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
|
||||
return NULL;
|
||||
|
||||
if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
|
||||
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
|
||||
if (!handle)
|
||||
return NULL;
|
||||
memset(handle, 0, sizeof(struct input_handle));
|
||||
|
||||
handle->dev = dev;
|
||||
handle->handler = handler;
|
||||
handle->name = "kbd";
|
||||
|
||||
input_open_device(handle);
|
||||
kbd_refresh_leds(handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
@ -1318,6 +1316,24 @@ static void kbd_disconnect(struct input_handle *handle)
|
|||
kfree(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start keyboard handler on the new keyboard by refreshing LED state to
|
||||
* match the rest of the system.
|
||||
*/
|
||||
static void kbd_start(struct input_handle *handle)
|
||||
{
|
||||
unsigned char leds = ledstate;
|
||||
|
||||
tasklet_disable(&keyboard_tasklet);
|
||||
if (leds != 0xff) {
|
||||
input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
|
||||
input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
|
||||
input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
|
||||
input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
tasklet_enable(&keyboard_tasklet);
|
||||
}
|
||||
|
||||
static struct input_device_id kbd_ids[] = {
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
|
||||
|
@ -1338,6 +1354,7 @@ static struct input_handler kbd_handler = {
|
|||
.event = kbd_event,
|
||||
.connect = kbd_connect,
|
||||
.disconnect = kbd_disconnect,
|
||||
.start = kbd_start,
|
||||
.name = "kbd",
|
||||
.id_table = kbd_ids,
|
||||
};
|
||||
|
@ -1346,15 +1363,15 @@ int __init kbd_init(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
|
||||
kbd0.ledmode = LED_SHOW_FLAGS;
|
||||
kbd0.lockstate = KBD_DEFLOCK;
|
||||
kbd0.slockstate = 0;
|
||||
kbd0.modeflags = KBD_DEFMODE;
|
||||
kbd0.kbdmode = VC_XLATE;
|
||||
|
||||
for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
|
||||
kbd_table[i] = kbd0;
|
||||
for (i = 0; i < MAX_NR_CONSOLES; i++) {
|
||||
kbd_table[i].ledflagstate = KBD_DEFLEDS;
|
||||
kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
|
||||
kbd_table[i].ledmode = LED_SHOW_FLAGS;
|
||||
kbd_table[i].lockstate = KBD_DEFLOCK;
|
||||
kbd_table[i].slockstate = 0;
|
||||
kbd_table[i].modeflags = KBD_DEFMODE;
|
||||
kbd_table[i].kbdmode = VC_XLATE;
|
||||
}
|
||||
|
||||
input_register_handler(&kbd_handler);
|
||||
|
||||
|
|
|
@ -284,39 +284,69 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
|
|||
* SYSFS INTERFACE *
|
||||
*********************************************************************/
|
||||
|
||||
static struct cpufreq_governor *__find_governor(const char *str_governor)
|
||||
{
|
||||
struct cpufreq_governor *t;
|
||||
|
||||
list_for_each_entry(t, &cpufreq_governor_list, governor_list)
|
||||
if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN))
|
||||
return t;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpufreq_parse_governor - parse a governor string
|
||||
*/
|
||||
static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
|
||||
struct cpufreq_governor **governor)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
if (!cpufreq_driver)
|
||||
return -EINVAL;
|
||||
goto out;
|
||||
|
||||
if (cpufreq_driver->setpolicy) {
|
||||
if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
|
||||
*policy = CPUFREQ_POLICY_PERFORMANCE;
|
||||
return 0;
|
||||
err = 0;
|
||||
} else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
|
||||
*policy = CPUFREQ_POLICY_POWERSAVE;
|
||||
return 0;
|
||||
err = 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
} else {
|
||||
} else if (cpufreq_driver->target) {
|
||||
struct cpufreq_governor *t;
|
||||
|
||||
mutex_lock(&cpufreq_governor_mutex);
|
||||
if (!cpufreq_driver || !cpufreq_driver->target)
|
||||
goto out;
|
||||
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
|
||||
if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
|
||||
*governor = t;
|
||||
|
||||
t = __find_governor(str_governor);
|
||||
|
||||
if (t == NULL) {
|
||||
char *name = kasprintf(GFP_KERNEL, "cpufreq_%s", str_governor);
|
||||
|
||||
if (name) {
|
||||
int ret;
|
||||
|
||||
mutex_unlock(&cpufreq_governor_mutex);
|
||||
return 0;
|
||||
ret = request_module(name);
|
||||
mutex_lock(&cpufreq_governor_mutex);
|
||||
|
||||
if (ret == 0)
|
||||
t = __find_governor(str_governor);
|
||||
}
|
||||
|
||||
kfree(name);
|
||||
}
|
||||
out:
|
||||
|
||||
if (t != NULL) {
|
||||
*governor = t;
|
||||
err = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&cpufreq_governor_mutex);
|
||||
}
|
||||
return -EINVAL;
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1265,23 +1295,21 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
|
|||
|
||||
int cpufreq_register_governor(struct cpufreq_governor *governor)
|
||||
{
|
||||
struct cpufreq_governor *t;
|
||||
int err;
|
||||
|
||||
if (!governor)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cpufreq_governor_mutex);
|
||||
|
||||
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
|
||||
if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) {
|
||||
mutex_unlock(&cpufreq_governor_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
err = -EBUSY;
|
||||
if (__find_governor(governor->name) == NULL) {
|
||||
err = 0;
|
||||
list_add(&governor->governor_list, &cpufreq_governor_list);
|
||||
}
|
||||
list_add(&governor->governor_list, &cpufreq_governor_list);
|
||||
|
||||
mutex_unlock(&cpufreq_governor_mutex);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_register_governor);
|
||||
|
||||
|
@ -1343,6 +1371,11 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
|
|||
|
||||
memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo));
|
||||
|
||||
if (policy->min > data->min && policy->min > policy->max) {
|
||||
ret = -EINVAL;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
/* verify the cpu speed can be set within this limit */
|
||||
ret = cpufreq_driver->verify(policy);
|
||||
if (ret)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/rcupdate.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define EDAC_MC_LABEL_LEN 31
|
||||
#define MC_PROC_NAME_MAX_LEN 7
|
||||
|
|
|
@ -232,7 +232,7 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface)
|
|||
unsigned long timeout;
|
||||
|
||||
timeout = jiffies + POLL_TIMEOUT;
|
||||
while (time_before(jiffies, timeout)) {
|
||||
while (1) {
|
||||
status = inb(ACBST);
|
||||
|
||||
/* Reset the status register to avoid the hang */
|
||||
|
@ -242,7 +242,10 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface)
|
|||
scx200_acb_machine(iface, status);
|
||||
return;
|
||||
}
|
||||
yield();
|
||||
if (time_after(jiffies, timeout))
|
||||
break;
|
||||
cpu_relax();
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
dev_err(&iface->adapter.dev, "timeout in state %s\n",
|
||||
|
|
|
@ -180,6 +180,36 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
|
|||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = OFF_BOARD,
|
||||
},{ /* 15 */
|
||||
.name = "JMB361",
|
||||
.init_hwif = init_hwif_generic,
|
||||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = OFF_BOARD,
|
||||
},{ /* 16 */
|
||||
.name = "JMB363",
|
||||
.init_hwif = init_hwif_generic,
|
||||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = OFF_BOARD,
|
||||
},{ /* 17 */
|
||||
.name = "JMB365",
|
||||
.init_hwif = init_hwif_generic,
|
||||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = OFF_BOARD,
|
||||
},{ /* 18 */
|
||||
.name = "JMB366",
|
||||
.init_hwif = init_hwif_generic,
|
||||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = OFF_BOARD,
|
||||
},{ /* 19 */
|
||||
.name = "JMB368",
|
||||
.init_hwif = init_hwif_generic,
|
||||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = OFF_BOARD,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2515,6 +2515,9 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
|
|||
sdev->skip_ms_page_8 = 1;
|
||||
if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
|
||||
sdev->fix_capacity = 1;
|
||||
if (scsi_id->ne->guid_vendor_id == 0x0010b9 && /* Maxtor's OUI */
|
||||
(sdev->type == TYPE_DISK || sdev->type == TYPE_RBC))
|
||||
sdev->allow_restart = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,14 +127,10 @@ static int evdev_open(struct inode * inode, struct file * file)
|
|||
{
|
||||
struct evdev_list *list;
|
||||
int i = iminor(inode) - EVDEV_MINOR_BASE;
|
||||
int accept_err;
|
||||
|
||||
if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist)
|
||||
return -ENODEV;
|
||||
|
||||
if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file)))
|
||||
return accept_err;
|
||||
|
||||
if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -260,7 +256,7 @@ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_
|
|||
|
||||
if (evdev_event_from_user(buffer + retval, &event))
|
||||
return -EFAULT;
|
||||
input_event(list->evdev->handle.dev, event.type, event.code, event.value);
|
||||
input_inject_event(&list->evdev->handle, event.type, event.code, event.value);
|
||||
retval += evdev_event_size();
|
||||
}
|
||||
|
||||
|
@ -428,8 +424,8 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
|
|||
if (get_user(v, ip + 1))
|
||||
return -EFAULT;
|
||||
|
||||
input_event(dev, EV_REP, REP_DELAY, u);
|
||||
input_event(dev, EV_REP, REP_PERIOD, v);
|
||||
input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u);
|
||||
input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -106,10 +106,10 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
|
|||
gp->gameport = port;
|
||||
gp->res_port = request_region(port->io, 0x10, "FM801 GP");
|
||||
if (!gp->res_port) {
|
||||
kfree(gp);
|
||||
gameport_free_port(port);
|
||||
printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n",
|
||||
port->io, port->io + 0x0f);
|
||||
gameport_free_port(port);
|
||||
kfree(gp);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ static LIST_HEAD(gameport_list);
|
|||
|
||||
static struct bus_type gameport_bus;
|
||||
|
||||
static void gameport_add_driver(struct gameport_driver *drv);
|
||||
static void gameport_add_port(struct gameport *gameport);
|
||||
static void gameport_destroy_port(struct gameport *gameport);
|
||||
static void gameport_reconnect_port(struct gameport *gameport);
|
||||
|
@ -211,8 +212,14 @@ static void gameport_release_driver(struct gameport *gameport)
|
|||
|
||||
static void gameport_find_driver(struct gameport *gameport)
|
||||
{
|
||||
int error;
|
||||
|
||||
down_write(&gameport_bus.subsys.rwsem);
|
||||
device_attach(&gameport->dev);
|
||||
error = device_attach(&gameport->dev);
|
||||
if (error < 0)
|
||||
printk(KERN_WARNING
|
||||
"gameport: device_attach() failed for %s (%s), error: %d\n",
|
||||
gameport->phys, gameport->name, error);
|
||||
up_write(&gameport_bus.subsys.rwsem);
|
||||
}
|
||||
|
||||
|
@ -316,7 +323,6 @@ static void gameport_remove_duplicate_events(struct gameport_event *event)
|
|||
spin_unlock_irqrestore(&gameport_event_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
static struct gameport_event *gameport_get_event(void)
|
||||
{
|
||||
struct gameport_event *event;
|
||||
|
@ -342,7 +348,6 @@ static struct gameport_event *gameport_get_event(void)
|
|||
static void gameport_handle_event(void)
|
||||
{
|
||||
struct gameport_event *event;
|
||||
struct gameport_driver *gameport_drv;
|
||||
|
||||
mutex_lock(&gameport_mutex);
|
||||
|
||||
|
@ -369,8 +374,7 @@ static void gameport_handle_event(void)
|
|||
break;
|
||||
|
||||
case GAMEPORT_REGISTER_DRIVER:
|
||||
gameport_drv = event->object;
|
||||
driver_register(&gameport_drv->driver);
|
||||
gameport_add_driver(event->object);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -532,6 +536,7 @@ static void gameport_init_port(struct gameport *gameport)
|
|||
if (gameport->parent)
|
||||
gameport->dev.parent = &gameport->parent->dev;
|
||||
|
||||
INIT_LIST_HEAD(&gameport->node);
|
||||
spin_lock_init(&gameport->timer_lock);
|
||||
init_timer(&gameport->poll_timer);
|
||||
gameport->poll_timer.function = gameport_run_poll_handler;
|
||||
|
@ -544,6 +549,8 @@ static void gameport_init_port(struct gameport *gameport)
|
|||
*/
|
||||
static void gameport_add_port(struct gameport *gameport)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (gameport->parent)
|
||||
gameport->parent->child = gameport;
|
||||
|
||||
|
@ -558,8 +565,13 @@ static void gameport_add_port(struct gameport *gameport)
|
|||
printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n",
|
||||
gameport->name, gameport->phys, gameport->speed);
|
||||
|
||||
device_add(&gameport->dev);
|
||||
gameport->registered = 1;
|
||||
error = device_add(&gameport->dev);
|
||||
if (error)
|
||||
printk(KERN_ERR
|
||||
"gameport: device_add() failed for %s (%s), error: %d\n",
|
||||
gameport->phys, gameport->name, error);
|
||||
else
|
||||
gameport->registered = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -583,10 +595,11 @@ static void gameport_destroy_port(struct gameport *gameport)
|
|||
|
||||
if (gameport->registered) {
|
||||
device_del(&gameport->dev);
|
||||
list_del_init(&gameport->node);
|
||||
gameport->registered = 0;
|
||||
}
|
||||
|
||||
list_del_init(&gameport->node);
|
||||
|
||||
gameport_remove_pending_events(gameport);
|
||||
put_device(&gameport->dev);
|
||||
}
|
||||
|
@ -704,11 +717,22 @@ static int gameport_driver_remove(struct device *dev)
|
|||
}
|
||||
|
||||
static struct bus_type gameport_bus = {
|
||||
.name = "gameport",
|
||||
.probe = gameport_driver_probe,
|
||||
.remove = gameport_driver_remove,
|
||||
.name = "gameport",
|
||||
.probe = gameport_driver_probe,
|
||||
.remove = gameport_driver_remove,
|
||||
};
|
||||
|
||||
static void gameport_add_driver(struct gameport_driver *drv)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = driver_register(&drv->driver);
|
||||
if (error)
|
||||
printk(KERN_ERR
|
||||
"gameport: driver_register() failed for %s, error: %d\n",
|
||||
drv->driver.name, error);
|
||||
}
|
||||
|
||||
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
|
||||
{
|
||||
drv->driver.bus = &gameport_bus;
|
||||
|
@ -778,16 +802,24 @@ void gameport_close(struct gameport *gameport)
|
|||
|
||||
static int __init gameport_init(void)
|
||||
{
|
||||
gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
|
||||
if (IS_ERR(gameport_task)) {
|
||||
printk(KERN_ERR "gameport: Failed to start kgameportd\n");
|
||||
return PTR_ERR(gameport_task);
|
||||
}
|
||||
int error;
|
||||
|
||||
gameport_bus.dev_attrs = gameport_device_attrs;
|
||||
gameport_bus.drv_attrs = gameport_driver_attrs;
|
||||
gameport_bus.match = gameport_bus_match;
|
||||
bus_register(&gameport_bus);
|
||||
error = bus_register(&gameport_bus);
|
||||
if (error) {
|
||||
printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
|
||||
if (IS_ERR(gameport_task)) {
|
||||
bus_unregister(&gameport_bus);
|
||||
error = PTR_ERR(gameport_task);
|
||||
printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,16 @@ static LIST_HEAD(input_handler_list);
|
|||
|
||||
static struct input_handler *input_table[8];
|
||||
|
||||
/**
|
||||
* input_event() - report new input event
|
||||
* @handle: device that generated the event
|
||||
* @type: type of the event
|
||||
* @code: event code
|
||||
* @value: value of the event
|
||||
*
|
||||
* This function should be used by drivers implementing various input devices
|
||||
* See also input_inject_event()
|
||||
*/
|
||||
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
struct input_handle *handle;
|
||||
|
@ -183,6 +193,23 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
|
|||
}
|
||||
EXPORT_SYMBOL(input_event);
|
||||
|
||||
/**
|
||||
* input_inject_event() - send input event from input handler
|
||||
* @handle: input handle to send event through
|
||||
* @type: type of the event
|
||||
* @code: event code
|
||||
* @value: value of the event
|
||||
*
|
||||
* Similar to input_event() but will ignore event if device is "grabbed" and handle
|
||||
* injecting event is not the one that owns the device.
|
||||
*/
|
||||
void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
if (!handle->dev->grab || handle->dev->grab == handle)
|
||||
input_event(handle->dev, type, code, value);
|
||||
}
|
||||
EXPORT_SYMBOL(input_inject_event);
|
||||
|
||||
static void input_repeat_key(unsigned long data)
|
||||
{
|
||||
struct input_dev *dev = (void *) data;
|
||||
|
@ -197,15 +224,6 @@ static void input_repeat_key(unsigned long data)
|
|||
mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD]));
|
||||
}
|
||||
|
||||
int input_accept_process(struct input_handle *handle, struct file *file)
|
||||
{
|
||||
if (handle->dev->accept)
|
||||
return handle->dev->accept(handle->dev, file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(input_accept_process);
|
||||
|
||||
int input_grab_device(struct input_handle *handle)
|
||||
{
|
||||
if (handle->dev->grab)
|
||||
|
@ -218,8 +236,15 @@ EXPORT_SYMBOL(input_grab_device);
|
|||
|
||||
void input_release_device(struct input_handle *handle)
|
||||
{
|
||||
if (handle->dev->grab == handle)
|
||||
handle->dev->grab = NULL;
|
||||
struct input_dev *dev = handle->dev;
|
||||
|
||||
if (dev->grab == handle) {
|
||||
dev->grab = NULL;
|
||||
|
||||
list_for_each_entry(handle, &dev->h_list, d_node)
|
||||
if (handle->handler->start)
|
||||
handle->handler->start(handle);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(input_release_device);
|
||||
|
||||
|
@ -963,8 +988,11 @@ int input_register_device(struct input_dev *dev)
|
|||
list_for_each_entry(handler, &input_handler_list, node)
|
||||
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
|
||||
if ((id = input_match_device(handler->id_table, dev)))
|
||||
if ((handle = handler->connect(handler, dev, id)))
|
||||
if ((handle = handler->connect(handler, dev, id))) {
|
||||
input_link_handle(handle);
|
||||
if (handler->start)
|
||||
handler->start(handle);
|
||||
}
|
||||
|
||||
input_wakeup_procfs_readers();
|
||||
|
||||
|
@ -1028,8 +1056,11 @@ void input_register_handler(struct input_handler *handler)
|
|||
list_for_each_entry(dev, &input_dev_list, node)
|
||||
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
|
||||
if ((id = input_match_device(handler->id_table, dev)))
|
||||
if ((handle = handler->connect(handler, dev, id)))
|
||||
if ((handle = handler->connect(handler, dev, id))) {
|
||||
input_link_handle(handle);
|
||||
if (handler->start)
|
||||
handler->start(handle);
|
||||
}
|
||||
|
||||
input_wakeup_procfs_readers();
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ static struct iforce_device iforce_device[] = {
|
|||
{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //?
|
||||
{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //?
|
||||
{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //?
|
||||
{ 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce },
|
||||
{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce }
|
||||
};
|
||||
|
||||
|
@ -222,22 +223,22 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id)
|
|||
int err = 0;
|
||||
struct iforce_core_effect* core_effect;
|
||||
|
||||
/* Check who is trying to erase this effect */
|
||||
if (iforce->core_effects[effect_id].owner != current->pid) {
|
||||
printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, iforce->core_effects[effect_id].owner);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
core_effect = iforce->core_effects + effect_id;
|
||||
core_effect = &iforce->core_effects[effect_id];
|
||||
|
||||
/* Check who is trying to erase this effect */
|
||||
if (core_effect->owner != current->pid) {
|
||||
printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, core_effect->owner);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
|
||||
err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk));
|
||||
err = release_resource(&core_effect->mod1_chunk);
|
||||
|
||||
if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
|
||||
err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk));
|
||||
err = release_resource(&core_effect->mod2_chunk);
|
||||
|
||||
/*TODO: remember to change that if more FF_MOD* bits are added */
|
||||
core_effect->flags[0] = 0;
|
||||
|
|
|
@ -50,7 +50,7 @@ MODULE_LICENSE("GPL");
|
|||
*/
|
||||
|
||||
#define SPACEBALL_MAX_LENGTH 128
|
||||
#define SPACEBALL_MAX_ID 8
|
||||
#define SPACEBALL_MAX_ID 9
|
||||
|
||||
#define SPACEBALL_1003 1
|
||||
#define SPACEBALL_2003B 3
|
||||
|
|
|
@ -482,6 +482,55 @@ out:
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int atkbd_set_repeat_rate(struct atkbd *atkbd)
|
||||
{
|
||||
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 input_dev *dev = atkbd->dev;
|
||||
unsigned char param;
|
||||
int i = 0, j = 0;
|
||||
|
||||
while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD])
|
||||
i++;
|
||||
dev->rep[REP_PERIOD] = period[i];
|
||||
|
||||
while (j < ARRAY_SIZE(period) - 1 && delay[j] < dev->rep[REP_DELAY])
|
||||
j++;
|
||||
dev->rep[REP_DELAY] = delay[j];
|
||||
|
||||
param = i | (j << 5);
|
||||
return ps2_command(&atkbd->ps2dev, ¶m, ATKBD_CMD_SETREP);
|
||||
}
|
||||
|
||||
static int atkbd_set_leds(struct atkbd *atkbd)
|
||||
{
|
||||
struct input_dev *dev = atkbd->dev;
|
||||
unsigned char param[2];
|
||||
|
||||
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);
|
||||
if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS))
|
||||
return -1;
|
||||
|
||||
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);
|
||||
if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* atkbd_event_work() is used to complete processing of events that
|
||||
* can not be processed by input_event() which is often called from
|
||||
|
@ -490,47 +539,15 @@ out:
|
|||
|
||||
static void atkbd_event_work(void *data)
|
||||
{
|
||||
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;
|
||||
|
||||
mutex_lock(&atkbd->event_mutex);
|
||||
|
||||
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 (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
|
||||
atkbd_set_leds(atkbd);
|
||||
|
||||
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);
|
||||
}
|
||||
if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
|
||||
atkbd_set_repeat_rate(atkbd);
|
||||
|
||||
mutex_unlock(&atkbd->event_mutex);
|
||||
}
|
||||
|
@ -975,7 +992,6 @@ static int atkbd_reconnect(struct serio *serio)
|
|||
{
|
||||
struct atkbd *atkbd = serio_get_drvdata(serio);
|
||||
struct serio_driver *drv = serio->drv;
|
||||
unsigned char param[1];
|
||||
|
||||
if (!atkbd || !drv) {
|
||||
printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
|
||||
|
@ -985,10 +1001,6 @@ static int atkbd_reconnect(struct serio *serio)
|
|||
atkbd_disable(atkbd);
|
||||
|
||||
if (atkbd->write) {
|
||||
param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0)
|
||||
| (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0)
|
||||
| (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0);
|
||||
|
||||
if (atkbd_probe(atkbd))
|
||||
return -1;
|
||||
if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
|
||||
|
@ -996,8 +1008,13 @@ static int atkbd_reconnect(struct serio *serio)
|
|||
|
||||
atkbd_activate(atkbd);
|
||||
|
||||
if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS))
|
||||
return -1;
|
||||
/*
|
||||
* Restore repeat rate and LEDs (that were reset by atkbd_activate)
|
||||
* to pre-resume state
|
||||
*/
|
||||
if (!atkbd->softrepeat)
|
||||
atkbd_set_repeat_rate(atkbd);
|
||||
atkbd_set_leds(atkbd);
|
||||
}
|
||||
|
||||
atkbd_enable(atkbd);
|
||||
|
|
|
@ -94,7 +94,7 @@ static void call_bios(struct regs *regs)
|
|||
|
||||
static ssize_t __init locate_wistron_bios(void __iomem *base)
|
||||
{
|
||||
static const unsigned char __initdata signature[] =
|
||||
static unsigned char __initdata signature[] =
|
||||
{ 0x42, 0x21, 0x55, 0x30 };
|
||||
ssize_t offset;
|
||||
|
||||
|
@ -259,11 +259,11 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static struct key_entry keymap_empty[] = {
|
||||
static struct key_entry keymap_empty[] __initdata = {
|
||||
{ KE_END, 0 }
|
||||
};
|
||||
|
||||
static struct key_entry keymap_fs_amilo_pro_v2000[] = {
|
||||
static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
|
||||
{ KE_KEY, 0x01, KEY_HELP },
|
||||
{ KE_KEY, 0x11, KEY_PROG1 },
|
||||
{ KE_KEY, 0x12, KEY_PROG2 },
|
||||
|
@ -273,7 +273,7 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = {
|
|||
{ KE_END, 0 }
|
||||
};
|
||||
|
||||
static struct key_entry keymap_fujitsu_n3510[] = {
|
||||
static struct key_entry keymap_fujitsu_n3510[] __initdata = {
|
||||
{ KE_KEY, 0x11, KEY_PROG1 },
|
||||
{ KE_KEY, 0x12, KEY_PROG2 },
|
||||
{ KE_KEY, 0x36, KEY_WWW },
|
||||
|
@ -285,7 +285,7 @@ static struct key_entry keymap_fujitsu_n3510[] = {
|
|||
{ KE_END, 0 }
|
||||
};
|
||||
|
||||
static struct key_entry keymap_wistron_ms2111[] = {
|
||||
static struct key_entry keymap_wistron_ms2111[] __initdata = {
|
||||
{ KE_KEY, 0x11, KEY_PROG1 },
|
||||
{ KE_KEY, 0x12, KEY_PROG2 },
|
||||
{ KE_KEY, 0x13, KEY_PROG3 },
|
||||
|
@ -294,7 +294,7 @@ static struct key_entry keymap_wistron_ms2111[] = {
|
|||
{ KE_END, 0 }
|
||||
};
|
||||
|
||||
static struct key_entry keymap_wistron_ms2141[] = {
|
||||
static struct key_entry keymap_wistron_ms2141[] __initdata = {
|
||||
{ KE_KEY, 0x11, KEY_PROG1 },
|
||||
{ KE_KEY, 0x12, KEY_PROG2 },
|
||||
{ KE_WIFI, 0x30, 0 },
|
||||
|
@ -307,7 +307,7 @@ static struct key_entry keymap_wistron_ms2141[] = {
|
|||
{ KE_END, 0 }
|
||||
};
|
||||
|
||||
static struct key_entry keymap_acer_aspire_1500[] = {
|
||||
static struct key_entry keymap_acer_aspire_1500[] __initdata = {
|
||||
{ KE_KEY, 0x11, KEY_PROG1 },
|
||||
{ KE_KEY, 0x12, KEY_PROG2 },
|
||||
{ KE_WIFI, 0x30, 0 },
|
||||
|
@ -317,7 +317,7 @@ static struct key_entry keymap_acer_aspire_1500[] = {
|
|||
{ KE_END, 0 }
|
||||
};
|
||||
|
||||
static struct key_entry keymap_acer_travelmate_240[] = {
|
||||
static struct key_entry keymap_acer_travelmate_240[] __initdata = {
|
||||
{ KE_KEY, 0x31, KEY_MAIL },
|
||||
{ KE_KEY, 0x36, KEY_WWW },
|
||||
{ KE_KEY, 0x11, KEY_PROG1 },
|
||||
|
@ -327,7 +327,7 @@ static struct key_entry keymap_acer_travelmate_240[] = {
|
|||
{ KE_END, 0 }
|
||||
};
|
||||
|
||||
static struct key_entry keymap_aopen_1559as[] = {
|
||||
static struct key_entry keymap_aopen_1559as[] __initdata = {
|
||||
{ KE_KEY, 0x01, KEY_HELP },
|
||||
{ KE_KEY, 0x06, KEY_PROG3 },
|
||||
{ KE_KEY, 0x11, KEY_PROG1 },
|
||||
|
@ -343,7 +343,7 @@ static struct key_entry keymap_aopen_1559as[] = {
|
|||
* 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[] = {
|
||||
static struct dmi_system_id dmi_ids[] __initdata = {
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "Fujitsu-Siemens Amilo Pro V2000",
|
||||
|
|
|
@ -238,8 +238,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
|
|||
{ 100, PS2PP_KIND_MX, /* MX510 */
|
||||
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
|
||||
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
|
||||
{ 111, PS2PP_KIND_MX, /* MX300 */
|
||||
PS2PP_WHEEL | PS2PP_EXTRA_BTN | PS2PP_TASK_BTN },
|
||||
{ 111, PS2PP_KIND_MX, PS2PP_WHEEL | PS2PP_SIDE_BTN }, /* MX300 reports task button as side */
|
||||
{ 112, PS2PP_KIND_MX, /* MX500 */
|
||||
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
|
||||
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
|
||||
|
|
|
@ -183,21 +183,26 @@ static struct attribute_group trackpoint_attr_group = {
|
|||
.attrs = trackpoint_attrs,
|
||||
};
|
||||
|
||||
static void trackpoint_disconnect(struct psmouse *psmouse)
|
||||
static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id)
|
||||
{
|
||||
sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group);
|
||||
unsigned char param[2] = { 0 };
|
||||
|
||||
kfree(psmouse->private);
|
||||
psmouse->private = NULL;
|
||||
if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
|
||||
return -1;
|
||||
|
||||
if (param[0] != TP_MAGIC_IDENT)
|
||||
return -1;
|
||||
|
||||
if (firmware_id)
|
||||
*firmware_id = param[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trackpoint_sync(struct psmouse *psmouse)
|
||||
{
|
||||
unsigned char toggle;
|
||||
struct trackpoint_data *tp = psmouse->private;
|
||||
|
||||
if (!tp)
|
||||
return -1;
|
||||
unsigned char toggle;
|
||||
|
||||
/* Disable features that may make device unusable with this driver */
|
||||
trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle);
|
||||
|
@ -263,27 +268,38 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
|
|||
tp->ext_dev = TP_DEF_EXT_DEV;
|
||||
}
|
||||
|
||||
static void trackpoint_disconnect(struct psmouse *psmouse)
|
||||
{
|
||||
sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group);
|
||||
|
||||
kfree(psmouse->private);
|
||||
psmouse->private = NULL;
|
||||
}
|
||||
|
||||
static int trackpoint_reconnect(struct psmouse *psmouse)
|
||||
{
|
||||
if (trackpoint_start_protocol(psmouse, NULL))
|
||||
return -1;
|
||||
|
||||
if (trackpoint_sync(psmouse))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trackpoint_detect(struct psmouse *psmouse, int set_properties)
|
||||
{
|
||||
struct trackpoint_data *priv;
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
unsigned char firmware_id;
|
||||
unsigned char button_info;
|
||||
unsigned char param[2];
|
||||
|
||||
param[0] = param[1] = 0;
|
||||
|
||||
if (ps2_command(ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
|
||||
return -1;
|
||||
|
||||
if (param[0] != TP_MAGIC_IDENT)
|
||||
if (trackpoint_start_protocol(psmouse, &firmware_id))
|
||||
return -1;
|
||||
|
||||
if (!set_properties)
|
||||
return 0;
|
||||
|
||||
firmware_id = param[1];
|
||||
|
||||
if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
|
||||
printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n");
|
||||
button_info = 0;
|
||||
|
@ -296,7 +312,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties)
|
|||
psmouse->vendor = "IBM";
|
||||
psmouse->name = "TrackPoint";
|
||||
|
||||
psmouse->reconnect = trackpoint_sync;
|
||||
psmouse->reconnect = trackpoint_reconnect;
|
||||
psmouse->disconnect = trackpoint_disconnect;
|
||||
|
||||
trackpoint_defaults(priv);
|
||||
|
|
|
@ -177,6 +177,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (send && !param) {
|
||||
WARN_ON(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING);
|
||||
|
||||
serio_pause_rx(ps2dev->serio);
|
||||
|
|
|
@ -62,6 +62,7 @@ static LIST_HEAD(serio_list);
|
|||
|
||||
static struct bus_type serio_bus;
|
||||
|
||||
static void serio_add_driver(struct serio_driver *drv);
|
||||
static void serio_add_port(struct serio *serio);
|
||||
static void serio_destroy_port(struct serio *serio);
|
||||
static void serio_reconnect_port(struct serio *serio);
|
||||
|
@ -140,8 +141,14 @@ static void serio_release_driver(struct serio *serio)
|
|||
|
||||
static void serio_find_driver(struct serio *serio)
|
||||
{
|
||||
int error;
|
||||
|
||||
down_write(&serio_bus.subsys.rwsem);
|
||||
device_attach(&serio->dev);
|
||||
error = device_attach(&serio->dev);
|
||||
if (error < 0)
|
||||
printk(KERN_WARNING
|
||||
"serio: device_attach() failed for %s (%s), error: %d\n",
|
||||
serio->phys, serio->name, error);
|
||||
up_write(&serio_bus.subsys.rwsem);
|
||||
}
|
||||
|
||||
|
@ -272,7 +279,6 @@ static struct serio_event *serio_get_event(void)
|
|||
static void serio_handle_event(void)
|
||||
{
|
||||
struct serio_event *event;
|
||||
struct serio_driver *serio_drv;
|
||||
|
||||
mutex_lock(&serio_mutex);
|
||||
|
||||
|
@ -304,8 +310,7 @@ static void serio_handle_event(void)
|
|||
break;
|
||||
|
||||
case SERIO_REGISTER_DRIVER:
|
||||
serio_drv = event->object;
|
||||
driver_register(&serio_drv->driver);
|
||||
serio_add_driver(event->object);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -525,6 +530,7 @@ static void serio_init_port(struct serio *serio)
|
|||
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
INIT_LIST_HEAD(&serio->node);
|
||||
spin_lock_init(&serio->lock);
|
||||
mutex_init(&serio->drv_mutex);
|
||||
device_initialize(&serio->dev);
|
||||
|
@ -542,6 +548,8 @@ static void serio_init_port(struct serio *serio)
|
|||
*/
|
||||
static void serio_add_port(struct serio *serio)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (serio->parent) {
|
||||
serio_pause_rx(serio->parent);
|
||||
serio->parent->child = serio;
|
||||
|
@ -551,9 +559,19 @@ static void serio_add_port(struct serio *serio)
|
|||
list_add_tail(&serio->node, &serio_list);
|
||||
if (serio->start)
|
||||
serio->start(serio);
|
||||
device_add(&serio->dev);
|
||||
sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
|
||||
serio->registered = 1;
|
||||
error = device_add(&serio->dev);
|
||||
if (error)
|
||||
printk(KERN_ERR
|
||||
"serio: device_add() failed for %s (%s), error: %d\n",
|
||||
serio->phys, serio->name, error);
|
||||
else {
|
||||
serio->registered = 1;
|
||||
error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
|
||||
if (error)
|
||||
printk(KERN_ERR
|
||||
"serio: sysfs_create_group() failed for %s (%s), error: %d\n",
|
||||
serio->phys, serio->name, error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -583,10 +601,10 @@ static void serio_destroy_port(struct serio *serio)
|
|||
if (serio->registered) {
|
||||
sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group);
|
||||
device_del(&serio->dev);
|
||||
list_del_init(&serio->node);
|
||||
serio->registered = 0;
|
||||
}
|
||||
|
||||
list_del_init(&serio->node);
|
||||
serio_remove_pending_events(serio);
|
||||
put_device(&serio->dev);
|
||||
}
|
||||
|
@ -756,6 +774,17 @@ static struct bus_type serio_bus = {
|
|||
.remove = serio_driver_remove,
|
||||
};
|
||||
|
||||
static void serio_add_driver(struct serio_driver *drv)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = driver_register(&drv->driver);
|
||||
if (error)
|
||||
printk(KERN_ERR
|
||||
"serio: driver_register() failed for %s, error: %d\n",
|
||||
drv->driver.name, error);
|
||||
}
|
||||
|
||||
void __serio_register_driver(struct serio_driver *drv, struct module *owner)
|
||||
{
|
||||
drv->driver.bus = &serio_bus;
|
||||
|
@ -903,18 +932,26 @@ irqreturn_t serio_interrupt(struct serio *serio,
|
|||
|
||||
static int __init serio_init(void)
|
||||
{
|
||||
serio_task = kthread_run(serio_thread, NULL, "kseriod");
|
||||
if (IS_ERR(serio_task)) {
|
||||
printk(KERN_ERR "serio: Failed to start kseriod\n");
|
||||
return PTR_ERR(serio_task);
|
||||
}
|
||||
int error;
|
||||
|
||||
serio_bus.dev_attrs = serio_device_attrs;
|
||||
serio_bus.drv_attrs = serio_driver_attrs;
|
||||
serio_bus.match = serio_bus_match;
|
||||
serio_bus.uevent = serio_uevent;
|
||||
serio_bus.resume = serio_resume;
|
||||
bus_register(&serio_bus);
|
||||
error = bus_register(&serio_bus);
|
||||
if (error) {
|
||||
printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
serio_task = kthread_run(serio_thread, NULL, "kseriod");
|
||||
if (IS_ERR(serio_task)) {
|
||||
bus_unregister(&serio_bus);
|
||||
error = PTR_ERR(serio_task);
|
||||
printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -256,7 +256,6 @@ typedef struct
|
|||
#define NO_ORDER_CHECK_MASK 0x00000010
|
||||
#define LOW_CHANNEL_MASK 0x00000020
|
||||
#define NO_HSCX30_MASK 0x00000040
|
||||
#define MODE_MASK 0x00000080
|
||||
#define SET_BOARD 0x00001000
|
||||
#define SET_CRC4 0x00030000
|
||||
#define SET_L1_TRISTATE 0x00040000
|
||||
|
|
|
@ -162,7 +162,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
|
|||
goto out;
|
||||
}
|
||||
|
||||
min_spacing = mddev->array_size;
|
||||
min_spacing = conf->array_size;
|
||||
sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
|
||||
|
||||
/* min_spacing is the minimum spacing that will fit the hash
|
||||
|
@ -171,7 +171,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
|
|||
* that is larger than min_spacing as use the size of that as
|
||||
* the actual spacing
|
||||
*/
|
||||
conf->hash_spacing = mddev->array_size;
|
||||
conf->hash_spacing = conf->array_size;
|
||||
for (i=0; i < cnt-1 ; i++) {
|
||||
sector_t sz = 0;
|
||||
int j;
|
||||
|
@ -228,7 +228,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
|
|||
curr_offset = 0;
|
||||
i = 0;
|
||||
for (curr_offset = 0;
|
||||
curr_offset < mddev->array_size;
|
||||
curr_offset < conf->array_size;
|
||||
curr_offset += conf->hash_spacing) {
|
||||
|
||||
while (i < mddev->raid_disks-1 &&
|
||||
|
|
|
@ -393,7 +393,7 @@ static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth)
|
|||
state->bandwidth = bandwidth;
|
||||
|
||||
if (state->dst_type != DST_TYPE_IS_TERR)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (bandwidth) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
|
@ -462,7 +462,7 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate)
|
|||
|
||||
state->symbol_rate = srate;
|
||||
if (state->dst_type == DST_TYPE_IS_TERR) {
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
|
||||
srate /= 1000;
|
||||
|
@ -504,7 +504,7 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate)
|
|||
static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
|
||||
{
|
||||
if (state->dst_type != DST_TYPE_IS_CABLE)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
state->modulation = modulation;
|
||||
switch (modulation) {
|
||||
|
@ -1234,7 +1234,7 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
|
|||
goto error;
|
||||
}
|
||||
if (write_dst(state, data, len)) {
|
||||
dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
|
||||
dprintk(verbose, DST_INFO, 1, "Trying to recover.. ");
|
||||
if ((dst_error_recovery(state)) < 0) {
|
||||
dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
|
||||
goto error;
|
||||
|
@ -1328,15 +1328,13 @@ static int dst_tone_power_cmd(struct dst_state *state)
|
|||
{
|
||||
u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
|
||||
|
||||
if (state->dst_type == DST_TYPE_IS_TERR)
|
||||
return 0;
|
||||
if (state->dst_type != DST_TYPE_IS_SAT)
|
||||
return -EOPNOTSUPP;
|
||||
paket[4] = state->tx_tuna[4];
|
||||
paket[2] = state->tx_tuna[2];
|
||||
paket[3] = state->tx_tuna[3];
|
||||
paket[7] = dst_check_sum (paket, 7);
|
||||
dst_command(state, paket, 8);
|
||||
|
||||
return 0;
|
||||
return dst_command(state, paket, 8);
|
||||
}
|
||||
|
||||
static int dst_get_tuna(struct dst_state *state)
|
||||
|
@ -1465,7 +1463,7 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd
|
|||
u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
|
||||
|
||||
if (state->dst_type != DST_TYPE_IS_SAT)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
if (cmd->msg_len > 0 && cmd->msg_len < 5)
|
||||
memcpy(&paket[3], cmd->msg, cmd->msg_len);
|
||||
else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
|
||||
|
@ -1473,18 +1471,17 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd
|
|||
else
|
||||
return -EINVAL;
|
||||
paket[7] = dst_check_sum(&paket[0], 7);
|
||||
dst_command(state, paket, 8);
|
||||
return 0;
|
||||
return dst_command(state, paket, 8);
|
||||
}
|
||||
|
||||
static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
|
||||
{
|
||||
int need_cmd;
|
||||
int need_cmd, retval = 0;
|
||||
struct dst_state *state = fe->demodulator_priv;
|
||||
|
||||
state->voltage = voltage;
|
||||
if (state->dst_type != DST_TYPE_IS_SAT)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
need_cmd = 0;
|
||||
|
||||
|
@ -1506,9 +1503,9 @@ static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
|
|||
}
|
||||
|
||||
if (need_cmd)
|
||||
dst_tone_power_cmd(state);
|
||||
retval = dst_tone_power_cmd(state);
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
||||
|
@ -1517,7 +1514,7 @@ static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
|||
|
||||
state->tone = tone;
|
||||
if (state->dst_type != DST_TYPE_IS_SAT)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (tone) {
|
||||
case SEC_TONE_OFF:
|
||||
|
@ -1533,9 +1530,7 @@ static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
|||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
dst_tone_power_cmd(state);
|
||||
|
||||
return 0;
|
||||
return dst_tone_power_cmd(state);
|
||||
}
|
||||
|
||||
static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
|
||||
|
@ -1543,7 +1538,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
|
|||
struct dst_state *state = fe->demodulator_priv;
|
||||
|
||||
if (state->dst_type != DST_TYPE_IS_SAT)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
state->minicmd = minicmd;
|
||||
switch (minicmd) {
|
||||
case SEC_MINI_A:
|
||||
|
@ -1553,9 +1548,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
|
|||
state->tx_tuna[3] = 0xff;
|
||||
break;
|
||||
}
|
||||
dst_tone_power_cmd(state);
|
||||
|
||||
return 0;
|
||||
return dst_tone_power_cmd(state);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1608,28 +1601,31 @@ static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
|||
{
|
||||
struct dst_state *state = fe->demodulator_priv;
|
||||
|
||||
dst_get_signal(state);
|
||||
int retval = dst_get_signal(state);
|
||||
*strength = state->decode_strength;
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
struct dst_state *state = fe->demodulator_priv;
|
||||
|
||||
dst_get_signal(state);
|
||||
int retval = dst_get_signal(state);
|
||||
*snr = state->decode_snr;
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
|
||||
{
|
||||
int retval = -EINVAL;
|
||||
struct dst_state *state = fe->demodulator_priv;
|
||||
|
||||
if (p != NULL) {
|
||||
dst_set_freq(state, p->frequency);
|
||||
retval = dst_set_freq(state, p->frequency);
|
||||
if(retval != 0)
|
||||
return retval;
|
||||
dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
|
||||
|
||||
if (state->dst_type == DST_TYPE_IS_SAT) {
|
||||
|
@ -1647,10 +1643,10 @@ static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet
|
|||
dst_set_symbolrate(state, p->u.qam.symbol_rate);
|
||||
dst_set_modulation(state, p->u.qam.modulation);
|
||||
}
|
||||
dst_write_tuna(fe);
|
||||
retval = dst_write_tuna(fe);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int dst_tune_frontend(struct dvb_frontend* fe,
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# Makefile for the kernel DVB device drivers.
|
||||
#
|
||||
|
||||
dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
|
||||
dvb_ca_en50221.o dvb_frontend.o \
|
||||
dvb_net.o dvb_ringbuffer.o dvb_math.o
|
||||
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
|
||||
dvb_ca_en50221.o dvb_frontend.o \
|
||||
dvb_net.o dvb_ringbuffer.o dvb_math.o
|
||||
|
||||
obj-$(CONFIG_DVB_CORE) += dvb-core.o
|
||||
|
|
|
@ -350,5 +350,15 @@ config RADIO_ZOLTRIX_PORT
|
|||
help
|
||||
Enter the I/O port of your Zoltrix radio card.
|
||||
|
||||
endmenu
|
||||
config USB_DSBR
|
||||
tristate "D-Link USB FM radio support (EXPERIMENTAL)"
|
||||
depends on USB && VIDEO_V4L1 && EXPERIMENTAL
|
||||
---help---
|
||||
Say Y here if you want to connect this type of radio to your
|
||||
computer's USB port. Note that the audio is not digital, and
|
||||
you must connect the line out connector to a sound card or a
|
||||
set of speakers.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called dsbr100.
|
||||
endmenu
|
||||
|
|
|
@ -20,5 +20,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
|
|||
obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
|
||||
obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
|
||||
obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
|
||||
obj-$(CONFIG_USB_DSBR) += dsbr100.o
|
||||
|
||||
EXTRA_CFLAGS += -Isound
|
||||
|
|
|
@ -449,18 +449,6 @@ source "drivers/media/video/pvrusb2/Kconfig"
|
|||
|
||||
source "drivers/media/video/em28xx/Kconfig"
|
||||
|
||||
config USB_DSBR
|
||||
tristate "D-Link USB FM radio support (EXPERIMENTAL)"
|
||||
depends on USB && VIDEO_V4L1 && EXPERIMENTAL
|
||||
---help---
|
||||
Say Y here if you want to connect this type of radio to your
|
||||
computer's USB port. Note that the audio is not digital, and
|
||||
you must connect the line out connector to a sound card or a
|
||||
set of speakers.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called dsbr100.
|
||||
|
||||
source "drivers/media/video/usbvideo/Kconfig"
|
||||
|
||||
source "drivers/media/video/et61x251/Kconfig"
|
||||
|
|
|
@ -77,7 +77,6 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
|
|||
obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
|
||||
|
||||
obj-$(CONFIG_USB_DABUSB) += dabusb.o
|
||||
obj-$(CONFIG_USB_DSBR) += dsbr100.o
|
||||
obj-$(CONFIG_USB_OV511) += ov511.o
|
||||
obj-$(CONFIG_USB_SE401) += se401.o
|
||||
obj-$(CONFIG_USB_STV680) += stv680.o
|
||||
|
@ -91,6 +90,7 @@ obj-$(CONFIG_USB_ZC0301) += zc0301/
|
|||
obj-$(CONFIG_USB_IBMCAM) += usbvideo/
|
||||
obj-$(CONFIG_USB_KONICAWC) += usbvideo/
|
||||
obj-$(CONFIG_USB_VICAM) += usbvideo/
|
||||
obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
|
||||
|
||||
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
struct video_tuner32 {
|
||||
compat_int_t tuner;
|
||||
char name[32];
|
||||
|
@ -107,6 +107,7 @@ struct video_window32 {
|
|||
compat_caddr_t clips;
|
||||
compat_int_t clipcount;
|
||||
};
|
||||
#endif
|
||||
|
||||
static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
|
@ -124,6 +125,7 @@ static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
/* You get back everything except the clips... */
|
||||
static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
|
||||
{
|
||||
|
@ -138,6 +140,7 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u
|
|||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct v4l2_clip32
|
||||
{
|
||||
|
@ -490,6 +493,7 @@ static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
struct video_code32
|
||||
{
|
||||
char loadwhat[16]; /* name or tag of file being passed */
|
||||
|
@ -517,6 +521,8 @@ static inline int microcode32(struct video_code *kp, struct video_code32 __user
|
|||
#define VIDIOCSFREQ32 _IOW('v',15, u32)
|
||||
#define VIDIOCSMICROCODE32 _IOW('v',27, struct video_code32)
|
||||
|
||||
#endif
|
||||
|
||||
/* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */
|
||||
#define VIDIOC_ENUMINPUT32 VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4)
|
||||
#define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32)
|
||||
|
@ -537,6 +543,7 @@ static inline int microcode32(struct video_code *kp, struct video_code32 __user
|
|||
#define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t)
|
||||
#define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32)
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
enum {
|
||||
MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
|
||||
};
|
||||
|
@ -601,14 +608,17 @@ static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
|
||||
return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
union {
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
struct video_tuner vt;
|
||||
struct video_buffer vb;
|
||||
struct video_window vw;
|
||||
struct video_code vc;
|
||||
#endif
|
||||
struct v4l2_format v2f;
|
||||
struct v4l2_buffer v2b;
|
||||
struct v4l2_framebuffer v2fb;
|
||||
|
@ -624,6 +634,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
|
||||
/* First, convert the command. */
|
||||
switch(cmd) {
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
|
||||
case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
|
||||
case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
|
||||
|
@ -631,6 +642,8 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
|
||||
case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
|
||||
case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
|
||||
case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break;
|
||||
#endif
|
||||
case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
|
||||
case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
|
||||
case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
|
||||
|
@ -647,10 +660,10 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
|
||||
case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
|
||||
case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
|
||||
case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break;
|
||||
};
|
||||
|
||||
switch(cmd) {
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCSTUNER:
|
||||
case VIDIOCGTUNER:
|
||||
err = get_video_tuner32(&karg.vt, up);
|
||||
|
@ -664,6 +677,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
break;
|
||||
|
||||
case VIDIOCSFREQ:
|
||||
#endif
|
||||
case VIDIOC_S_INPUT:
|
||||
case VIDIOC_OVERLAY:
|
||||
case VIDIOC_STREAMON:
|
||||
|
@ -717,18 +731,21 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
compatible_arg = 0;
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCGWIN:
|
||||
case VIDIOCGFBUF:
|
||||
case VIDIOCGFREQ:
|
||||
#endif
|
||||
case VIDIOC_G_FBUF:
|
||||
case VIDIOC_G_INPUT:
|
||||
compatible_arg = 0;
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCSMICROCODE:
|
||||
err = microcode32(&karg.vc, up);
|
||||
compatible_arg = 0;
|
||||
break;
|
||||
#endif
|
||||
};
|
||||
|
||||
if(err)
|
||||
goto out;
|
||||
|
||||
|
@ -743,6 +760,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
}
|
||||
if(err == 0) {
|
||||
switch(cmd) {
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCGTUNER:
|
||||
err = put_video_tuner32(&karg.vt, up);
|
||||
break;
|
||||
|
@ -754,7 +772,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
case VIDIOCGFBUF:
|
||||
err = put_video_buffer32(&karg.vb, up);
|
||||
break;
|
||||
|
||||
#endif
|
||||
case VIDIOC_G_FBUF:
|
||||
err = put_v4l2_framebuffer32(&karg.v2fb, up);
|
||||
break;
|
||||
|
@ -792,7 +810,9 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
|||
err = put_v4l2_input32(&karg.v2i, up);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCGFREQ:
|
||||
#endif
|
||||
case VIDIOC_G_INPUT:
|
||||
err = put_user(((u32)karg.vx), (u32 __user *)up);
|
||||
break;
|
||||
|
@ -810,6 +830,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
return ret;
|
||||
|
||||
switch (cmd) {
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCSWIN32:
|
||||
ret = do_set_window(file, cmd, arg);
|
||||
break;
|
||||
|
@ -820,6 +841,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
case VIDIOCSFBUF32:
|
||||
case VIDIOCGFREQ32:
|
||||
case VIDIOCSFREQ32:
|
||||
#endif
|
||||
case VIDIOC_QUERYCAP:
|
||||
case VIDIOC_ENUM_FMT:
|
||||
case VIDIOC_G_FMT32:
|
||||
|
@ -851,6 +873,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
ret = do_video_ioctl(file, cmd, arg);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
/* Little v, the video4linux ioctls (conflict?) */
|
||||
case VIDIOCGCAP:
|
||||
case VIDIOCGCHAN:
|
||||
|
@ -879,6 +902,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
case _IOR('v' , BASE_VIDIOCPRIVATE+7, int):
|
||||
ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
v4l_print_ioctl("compat_ioctl32", cmd);
|
||||
}
|
||||
|
|
|
@ -104,8 +104,8 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr)
|
|||
if (i2c_master_recv(client, buffer, 4) < 4)
|
||||
return 0;
|
||||
|
||||
return (buffer[0] << 24) | (buffer[1] << 16) |
|
||||
(buffer[2] << 8) | buffer[3];
|
||||
return (buffer[3] << 24) | (buffer[2] << 16) |
|
||||
(buffer[1] << 8) | buffer[0];
|
||||
}
|
||||
|
||||
int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask,
|
||||
|
|
|
@ -1225,7 +1225,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
|
|||
struct v4l2_format *f = arg;
|
||||
return cx8800_try_fmt(dev,fh,f);
|
||||
}
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
/* --- streaming capture ------------------------------------- */
|
||||
case VIDIOCGMBUF:
|
||||
{
|
||||
|
@ -1584,7 +1584,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
|
|||
*id = 0;
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCSTUNER:
|
||||
{
|
||||
struct video_tuner *v = arg;
|
||||
|
|
|
@ -961,10 +961,10 @@ int msp34xxg_thread(void *data)
|
|||
/* setup the chip*/
|
||||
msp34xxg_reset(client);
|
||||
state->std = state->radio ? 0x40 : msp_standard;
|
||||
if (state->std != 1)
|
||||
goto unmute;
|
||||
/* start autodetect */
|
||||
msp_write_dem(client, 0x20, state->std);
|
||||
if (state->std != 1)
|
||||
goto unmute;
|
||||
|
||||
/* watch autodetect */
|
||||
v4l_dbg(1, msp_debug, client, "started autodetect, waiting for result\n");
|
||||
|
|
|
@ -30,7 +30,7 @@ config USB_PWC
|
|||
|
||||
config USB_PWC_DEBUG
|
||||
bool "USB Philips Cameras verbose debug"
|
||||
depends USB_PWC
|
||||
depends on USB_PWC
|
||||
help
|
||||
Say Y here in order to have the pwc driver generate verbose debugging
|
||||
messages.
|
||||
|
|
|
@ -160,6 +160,7 @@ static struct file_operations pwc_fops = {
|
|||
.poll = pwc_video_poll,
|
||||
.mmap = pwc_video_mmap,
|
||||
.ioctl = pwc_video_ioctl,
|
||||
.compat_ioctl = v4l_compat_ioctl32,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
static struct video_device pwc_template = {
|
||||
|
|
|
@ -2087,7 +2087,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
|
|||
struct v4l2_format *f = arg;
|
||||
return saa7134_try_fmt(dev,fh,f);
|
||||
}
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case VIDIOCGMBUF:
|
||||
{
|
||||
struct video_mbuf *mbuf = arg;
|
||||
|
|
|
@ -1027,10 +1027,11 @@ static struct tuner_params tuner_tnf_5335mf_params[] = {
|
|||
/* 70-79 */
|
||||
/* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */
|
||||
|
||||
/* '+ 4' turns on the Low Noise Amplifier */
|
||||
static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = {
|
||||
{ 16 * 130.00 /*MHz*/, 0xce, 0x01, },
|
||||
{ 16 * 364.50 /*MHz*/, 0xce, 0x02, },
|
||||
{ 16 * 999.99 , 0xce, 0x08, },
|
||||
{ 16 * 130.00 /*MHz*/, 0xce, 0x01 + 4, },
|
||||
{ 16 * 364.50 /*MHz*/, 0xce, 0x02 + 4, },
|
||||
{ 16 * 999.99 , 0xce, 0x08 + 4, },
|
||||
};
|
||||
|
||||
static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
|
||||
|
@ -1060,10 +1061,11 @@ static struct tuner_params tuner_thomson_fe6600_params[] = {
|
|||
|
||||
/* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */
|
||||
|
||||
/* '+ 4' turns on the Low Noise Amplifier */
|
||||
static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = {
|
||||
{ 16 * 146.25 /*MHz*/, 0xce, 0x01, },
|
||||
{ 16 * 428.50 /*MHz*/, 0xce, 0x02, },
|
||||
{ 16 * 999.99 , 0xce, 0x08, },
|
||||
{ 16 * 146.25 /*MHz*/, 0xce, 0x01 + 4, },
|
||||
{ 16 * 428.50 /*MHz*/, 0xce, 0x02 + 4, },
|
||||
{ 16 * 999.99 , 0xce, 0x08 + 4, },
|
||||
};
|
||||
|
||||
static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = {
|
||||
|
|
|
@ -599,6 +599,10 @@ v4l_compat_translate_ioctl(struct inode *inode,
|
|||
dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
|
||||
break;
|
||||
}
|
||||
|
||||
pict->depth = ((fmt2->fmt.pix.bytesperline<<3)
|
||||
+ (fmt2->fmt.pix.width-1) )
|
||||
/fmt2->fmt.pix.width;
|
||||
pict->palette = pixelformat_to_palette(
|
||||
fmt2->fmt.pix.pixelformat);
|
||||
break;
|
||||
|
|
|
@ -202,7 +202,7 @@ static char *v4l2_memory_names[] = {
|
|||
/* ------------------------------------------------------------------ */
|
||||
/* debug help functions */
|
||||
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
static const char *v4l1_ioctls[] = {
|
||||
[_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
|
||||
[_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
|
||||
|
@ -301,7 +301,7 @@ static const char *v4l2_ioctls[] = {
|
|||
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
|
||||
|
||||
static const char *v4l2_int_ioctls[] = {
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
[_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
|
||||
[_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
|
||||
[_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
|
||||
|
@ -367,7 +367,7 @@ void v4l_printk_ioctl(unsigned int cmd)
|
|||
(_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
|
||||
v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
|
||||
break;
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
case 'v':
|
||||
printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
|
||||
(_IOC_NR(cmd) < V4L1_IOCTLS) ?
|
||||
|
|
|
@ -760,7 +760,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
|
|||
ret=vfd->vidioc_overlay(file, fh, *i);
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
/* --- streaming capture ------------------------------------- */
|
||||
case VIDIOCGMBUF:
|
||||
{
|
||||
|
|
|
@ -986,7 +986,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
|
|||
file->f_flags & O_NONBLOCK));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
|
||||
{
|
||||
struct vivi_fh *fh=priv;
|
||||
|
@ -1328,7 +1328,7 @@ static struct video_device vivi = {
|
|||
.vidioc_s_ctrl = vidioc_s_ctrl,
|
||||
.vidioc_streamon = vidioc_streamon,
|
||||
.vidioc_streamoff = vidioc_streamoff,
|
||||
#ifdef CONFIG_V4L1_COMPAT
|
||||
#ifdef CONFIG_VIDEO_V4L1_COMPAT
|
||||
.vidiocgmbuf = vidiocgmbuf,
|
||||
#endif
|
||||
.tvnorms = tvnorms,
|
||||
|
|
|
@ -79,7 +79,8 @@ static int mmc_queue_thread(void *d)
|
|||
spin_lock_irq(q->queue_lock);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (!blk_queue_plugged(q))
|
||||
mq->req = req = elv_next_request(q);
|
||||
req = elv_next_request(q);
|
||||
mq->req = req;
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
if (!req) {
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "wbsd.h"
|
||||
|
||||
#define DRIVER_NAME "wbsd"
|
||||
#define DRIVER_VERSION "1.5"
|
||||
#define DRIVER_VERSION "1.6"
|
||||
|
||||
#define DBG(x...) \
|
||||
pr_debug(DRIVER_NAME ": " x)
|
||||
|
@ -1439,13 +1439,13 @@ static int __devinit wbsd_scan(struct wbsd_host *host)
|
|||
|
||||
static int __devinit wbsd_request_region(struct wbsd_host *host, int base)
|
||||
{
|
||||
if (io & 0x7)
|
||||
if (base & 0x7)
|
||||
return -EINVAL;
|
||||
|
||||
if (!request_region(base, 8, DRIVER_NAME))
|
||||
return -EIO;
|
||||
|
||||
host->base = io;
|
||||
host->base = base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1773,7 +1773,7 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma,
|
|||
/*
|
||||
* Request resources.
|
||||
*/
|
||||
ret = wbsd_request_resources(host, io, irq, dma);
|
||||
ret = wbsd_request_resources(host, base, irq, dma);
|
||||
if (ret) {
|
||||
wbsd_release_resources(host);
|
||||
wbsd_free_mmc(dev);
|
||||
|
@ -1861,6 +1861,7 @@ static void __devexit wbsd_shutdown(struct device *dev, int pnp)
|
|||
|
||||
static int __devinit wbsd_probe(struct platform_device *dev)
|
||||
{
|
||||
/* Use the module parameters for resources */
|
||||
return wbsd_init(&dev->dev, io, irq, dma, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -2425,7 +2425,7 @@ static int myri10ge_resume(struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
myri10ge_reset(mgp);
|
||||
myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096);
|
||||
myri10ge_dummy_rdma(mgp, 1);
|
||||
|
||||
/* Save configuration space to be restored if the
|
||||
* nic resets due to a parity error */
|
||||
|
|
|
@ -68,8 +68,8 @@
|
|||
|
||||
#define DRV_MODULE_NAME "tg3"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "3.64"
|
||||
#define DRV_MODULE_RELDATE "July 31, 2006"
|
||||
#define DRV_MODULE_VERSION "3.65"
|
||||
#define DRV_MODULE_RELDATE "August 07, 2006"
|
||||
|
||||
#define TG3_DEF_MAC_MODE 0
|
||||
#define TG3_DEF_RX_MODE 0
|
||||
|
@ -123,9 +123,6 @@
|
|||
TG3_RX_RCB_RING_SIZE(tp))
|
||||
#define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \
|
||||
TG3_TX_RING_SIZE)
|
||||
#define TX_BUFFS_AVAIL(TP) \
|
||||
((TP)->tx_pending - \
|
||||
(((TP)->tx_prod - (TP)->tx_cons) & (TG3_TX_RING_SIZE - 1)))
|
||||
#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1))
|
||||
|
||||
#define RX_PKT_BUF_SZ (1536 + tp->rx_offset + 64)
|
||||
|
@ -2987,6 +2984,13 @@ static void tg3_tx_recover(struct tg3 *tp)
|
|||
spin_unlock(&tp->lock);
|
||||
}
|
||||
|
||||
static inline u32 tg3_tx_avail(struct tg3 *tp)
|
||||
{
|
||||
smp_mb();
|
||||
return (tp->tx_pending -
|
||||
((tp->tx_prod - tp->tx_cons) & (TG3_TX_RING_SIZE - 1)));
|
||||
}
|
||||
|
||||
/* Tigon3 never reports partial packet sends. So we do not
|
||||
* need special logic to handle SKBs that have not had all
|
||||
* of their frags sent yet, like SunGEM does.
|
||||
|
@ -3038,12 +3042,20 @@ static void tg3_tx(struct tg3 *tp)
|
|||
|
||||
tp->tx_cons = sw_idx;
|
||||
|
||||
if (unlikely(netif_queue_stopped(tp->dev))) {
|
||||
spin_lock(&tp->tx_lock);
|
||||
/* Need to make the tx_cons update visible to tg3_start_xmit()
|
||||
* before checking for netif_queue_stopped(). Without the
|
||||
* memory barrier, there is a small possibility that tg3_start_xmit()
|
||||
* will miss it and cause the queue to be stopped forever.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
if (unlikely(netif_queue_stopped(tp->dev) &&
|
||||
(tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))) {
|
||||
netif_tx_lock(tp->dev);
|
||||
if (netif_queue_stopped(tp->dev) &&
|
||||
(TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH))
|
||||
(tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))
|
||||
netif_wake_queue(tp->dev);
|
||||
spin_unlock(&tp->tx_lock);
|
||||
netif_tx_unlock(tp->dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3101,7 +3113,6 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
|
|||
if (skb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
skb->dev = tp->dev;
|
||||
skb_reserve(skb, tp->rx_offset);
|
||||
|
||||
mapping = pci_map_single(tp->pdev, skb->data,
|
||||
|
@ -3274,7 +3285,6 @@ static int tg3_rx(struct tg3 *tp, int budget)
|
|||
if (copy_skb == NULL)
|
||||
goto drop_it_no_recycle;
|
||||
|
||||
copy_skb->dev = tp->dev;
|
||||
skb_reserve(copy_skb, 2);
|
||||
skb_put(copy_skb, len);
|
||||
pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
|
||||
|
@ -3797,7 +3807,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
* interrupt. Furthermore, IRQ processing runs lockless so we have
|
||||
* no IRQ context deadlocks to worry about either. Rejoice!
|
||||
*/
|
||||
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
|
||||
if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
|
||||
if (!netif_queue_stopped(dev)) {
|
||||
netif_stop_queue(dev);
|
||||
|
||||
|
@ -3893,12 +3903,10 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
|
||||
|
||||
tp->tx_prod = entry;
|
||||
if (unlikely(TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))) {
|
||||
spin_lock(&tp->tx_lock);
|
||||
if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
|
||||
netif_stop_queue(dev);
|
||||
if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH)
|
||||
if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)
|
||||
netif_wake_queue(tp->dev);
|
||||
spin_unlock(&tp->tx_lock);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
|
@ -3920,7 +3928,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
|
|||
struct sk_buff *segs, *nskb;
|
||||
|
||||
/* Estimate the number of fragments in the worst case */
|
||||
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->gso_segs * 3))) {
|
||||
if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) {
|
||||
netif_stop_queue(tp->dev);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
@ -3960,7 +3968,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
|
|||
* interrupt. Furthermore, IRQ processing runs lockless so we have
|
||||
* no IRQ context deadlocks to worry about either. Rejoice!
|
||||
*/
|
||||
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
|
||||
if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
|
||||
if (!netif_queue_stopped(dev)) {
|
||||
netif_stop_queue(dev);
|
||||
|
||||
|
@ -4110,12 +4118,10 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
|
|||
tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
|
||||
|
||||
tp->tx_prod = entry;
|
||||
if (unlikely(TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))) {
|
||||
spin_lock(&tp->tx_lock);
|
||||
if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
|
||||
netif_stop_queue(dev);
|
||||
if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH)
|
||||
if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)
|
||||
netif_wake_queue(tp->dev);
|
||||
spin_unlock(&tp->tx_lock);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
|
@ -11474,7 +11480,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
|||
tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA;
|
||||
#endif
|
||||
spin_lock_init(&tp->lock);
|
||||
spin_lock_init(&tp->tx_lock);
|
||||
spin_lock_init(&tp->indirect_lock);
|
||||
INIT_WORK(&tp->reset_task, tg3_reset_task, tp);
|
||||
|
||||
|
|
|
@ -2079,9 +2079,9 @@ struct tg3 {
|
|||
* lock: Held during reset, PHY access, timer, and when
|
||||
* updating tg3_flags and tg3_flags2.
|
||||
*
|
||||
* tx_lock: Held during tg3_start_xmit and tg3_tx only
|
||||
* when calling netif_[start|stop]_queue.
|
||||
* tg3_start_xmit is protected by netif_tx_lock.
|
||||
* netif_tx_lock: Held during tg3_start_xmit. tg3_tx holds
|
||||
* netif_tx_lock when it needs to call
|
||||
* netif_wake_queue.
|
||||
*
|
||||
* Both of these locks are to be held with BH safety.
|
||||
*
|
||||
|
@ -2118,8 +2118,6 @@ struct tg3 {
|
|||
u32 tx_cons;
|
||||
u32 tx_pending;
|
||||
|
||||
spinlock_t tx_lock;
|
||||
|
||||
struct tg3_tx_buffer_desc *tx_ring;
|
||||
struct tx_ring_info *tx_buffers;
|
||||
dma_addr_t tx_desc_mapping;
|
||||
|
|
|
@ -153,13 +153,6 @@ config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
|
|||
|
||||
When in doubt, say N.
|
||||
|
||||
config HOTPLUG_PCI_SHPC_PHPRM_LEGACY
|
||||
bool "For AMD SHPC only: Use $HRT for resource/configuration"
|
||||
depends on HOTPLUG_PCI_SHPC && !ACPI
|
||||
help
|
||||
Say Y here for AMD SHPC. You have to select this option if you are
|
||||
using this driver on platform with AMD SHPC.
|
||||
|
||||
config HOTPLUG_PCI_RPA
|
||||
tristate "RPA PCI Hotplug driver"
|
||||
depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
|
||||
|
|
|
@ -279,6 +279,11 @@ struct hpc_ops {
|
|||
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/actypes.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
|
||||
#define pciehp_get_hp_hw_control_from_firmware(dev) \
|
||||
pciehp_acpi_get_hp_hw_control_from_firmware(dev)
|
||||
static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
|
||||
|
|
|
@ -38,10 +38,6 @@
|
|||
|
||||
#include "../pci.h"
|
||||
#include "pciehp.h"
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/actypes.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#ifdef DEBUG
|
||||
#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
|
||||
#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
|
||||
|
|
|
@ -173,6 +173,9 @@ pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
|
|||
return;
|
||||
}
|
||||
|
||||
if (p->producer_consumer == ACPI_PRODUCER)
|
||||
return;
|
||||
|
||||
if (p->resource_type == ACPI_MEMORY_RANGE)
|
||||
pnpacpi_parse_allocated_memresource(res_table,
|
||||
p->minimum, p->address_length);
|
||||
|
@ -252,9 +255,14 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
|
|||
break;
|
||||
|
||||
case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
|
||||
if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
|
||||
return AE_OK;
|
||||
break;
|
||||
|
||||
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
|
||||
if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER)
|
||||
return AE_OK;
|
||||
|
||||
for (i = 0; i < res->data.extended_irq.interrupt_count; i++) {
|
||||
pnpacpi_parse_allocated_irqresource(res_table,
|
||||
res->data.extended_irq.interrupts[i],
|
||||
|
|
|
@ -76,7 +76,7 @@ struct tape_class_device *register_tape_dev(
|
|||
device,
|
||||
"%s", tcd->device_name
|
||||
);
|
||||
rc = PTR_ERR(tcd->class_device);
|
||||
rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
|
||||
if (rc)
|
||||
goto fail_with_cdev;
|
||||
rc = sysfs_create_link(
|
||||
|
|
|
@ -772,6 +772,7 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
|
|||
stsch(sch->schid, &sch->schib);
|
||||
|
||||
if (sch->schib.scsw.actl != 0 ||
|
||||
(sch->schib.scsw.stctl & SCSW_STCTL_STATUS_PEND) ||
|
||||
(cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) {
|
||||
/*
|
||||
* No final status yet or final status not yet delivered
|
||||
|
|
|
@ -263,6 +263,9 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
|
|||
/* Abuse intparm for error reporting. */
|
||||
if (IS_ERR(irb))
|
||||
cdev->private->intparm = -EIO;
|
||||
else if (irb->scsw.cc == 1)
|
||||
/* Retry for deferred condition code. */
|
||||
cdev->private->intparm = -EAGAIN;
|
||||
else if ((irb->scsw.dstat !=
|
||||
(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ||
|
||||
(irb->scsw.cstat != 0)) {
|
||||
|
|
|
@ -69,6 +69,7 @@ comment "The following drivers are not fully supported"
|
|||
config SCSI_CUMANA_1
|
||||
tristate "CumanaSCSI I support (EXPERIMENTAL)"
|
||||
depends on ARCH_ACORN && EXPERIMENTAL && SCSI
|
||||
select SCSI_SPI_ATTRS
|
||||
help
|
||||
This enables support for the Cumana SCSI I card. If you have an
|
||||
Acorn system with one of these, say Y. If unsure, say N.
|
||||
|
@ -76,6 +77,7 @@ config SCSI_CUMANA_1
|
|||
config SCSI_ECOSCSI
|
||||
tristate "EcoScsi support (EXPERIMENTAL)"
|
||||
depends on ARCH_ACORN && EXPERIMENTAL && (ARCH_ARC || ARCH_A5K) && SCSI
|
||||
select SCSI_SPI_ATTRS
|
||||
help
|
||||
This enables support for the EcoSCSI card -- a small card that sits
|
||||
in the Econet socket. If you have an Acorn system with one of these,
|
||||
|
@ -84,6 +86,7 @@ config SCSI_ECOSCSI
|
|||
config SCSI_OAK1
|
||||
tristate "Oak SCSI support (EXPERIMENTAL)"
|
||||
depends on ARCH_ACORN && EXPERIMENTAL && SCSI
|
||||
select SCSI_SPI_ATTRS
|
||||
help
|
||||
This enables support for the Oak SCSI card. If you have an Acorn
|
||||
system with one of these, say Y. If unsure, say N.
|
||||
|
|
|
@ -74,7 +74,7 @@ static inline void init_SCp(Scsi_Cmnd *SCpnt)
|
|||
unsigned long len = 0;
|
||||
int buf;
|
||||
|
||||
SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
|
||||
SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
|
||||
SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
|
||||
SCpnt->SCp.ptr = (char *)
|
||||
(page_address(SCpnt->SCp.buffer->page) +
|
||||
|
|
|
@ -567,8 +567,8 @@ static int piix_sata_prereset(struct ata_port *ap)
|
|||
present = 1;
|
||||
}
|
||||
|
||||
DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
|
||||
ap->id, pcs, present_mask);
|
||||
DPRINTK("ata%u: LEAVE, pcs=0x%x present=0x%x\n",
|
||||
ap->id, pcs, present);
|
||||
|
||||
if (!present) {
|
||||
ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n");
|
||||
|
@ -828,6 +828,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
|
|||
case IDE:
|
||||
WARN_ON((i & 1) || map[i + 1] != IDE);
|
||||
pinfo[i / 2] = piix_port_info[ich5_pata];
|
||||
pinfo[i / 2].private_data = hpriv;
|
||||
i++;
|
||||
printk(" IDE IDE");
|
||||
break;
|
||||
|
|
|
@ -5185,28 +5185,6 @@ void ata_host_stop (struct ata_host_set *host_set)
|
|||
iounmap(host_set->mmio_base);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_host_remove - Unregister SCSI host structure with upper layers
|
||||
* @ap: Port to unregister
|
||||
* @do_unregister: 1 if we fully unregister, 0 to just stop the port
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
|
||||
static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
|
||||
{
|
||||
struct Scsi_Host *sh = ap->host;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
if (do_unregister)
|
||||
scsi_remove_host(sh);
|
||||
|
||||
ap->ops->port_stop(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_init - Initialize an ata_device structure
|
||||
* @dev: Device structure to initialize
|
||||
|
@ -5532,8 +5510,11 @@ int ata_device_add(const struct ata_probe_ent *ent)
|
|||
|
||||
err_out:
|
||||
for (i = 0; i < count; i++) {
|
||||
ata_host_remove(host_set->ports[i], 1);
|
||||
scsi_host_put(host_set->ports[i]->host);
|
||||
struct ata_port *ap = host_set->ports[i];
|
||||
if (ap) {
|
||||
ap->ops->port_stop(ap);
|
||||
scsi_host_put(ap->host);
|
||||
}
|
||||
}
|
||||
err_free_ret:
|
||||
kfree(host_set);
|
||||
|
@ -5558,7 +5539,7 @@ void ata_port_detach(struct ata_port *ap)
|
|||
int i;
|
||||
|
||||
if (!ap->ops->error_handler)
|
||||
return;
|
||||
goto skip_eh;
|
||||
|
||||
/* tell EH we're leaving & flush EH */
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
@ -5594,6 +5575,7 @@ void ata_port_detach(struct ata_port *ap)
|
|||
cancel_delayed_work(&ap->hotplug_task);
|
||||
flush_workqueue(ata_aux_wq);
|
||||
|
||||
skip_eh:
|
||||
/* remove the associated SCSI host */
|
||||
scsi_remove_host(ap->host);
|
||||
}
|
||||
|
@ -5662,7 +5644,7 @@ int ata_scsi_release(struct Scsi_Host *host)
|
|||
DPRINTK("ENTER\n");
|
||||
|
||||
ap->ops->port_disable(ap);
|
||||
ata_host_remove(ap, 0);
|
||||
ap->ops->port_stop(ap);
|
||||
|
||||
DPRINTK("EXIT\n");
|
||||
return 1;
|
||||
|
|
|
@ -2353,6 +2353,19 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
|
|||
ata_gen_ata_desc_sense(qc);
|
||||
}
|
||||
|
||||
/* SCSI EH automatically locks door if sdev->locked is
|
||||
* set. Sometimes door lock request continues to
|
||||
* fail, for example, when no media is present. This
|
||||
* creates a loop - SCSI EH issues door lock which
|
||||
* fails and gets invoked again to acquire sense data
|
||||
* for the failed command.
|
||||
*
|
||||
* If door lock fails, always clear sdev->locked to
|
||||
* avoid this infinite loop.
|
||||
*/
|
||||
if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL)
|
||||
qc->dev->sdev->locked = 0;
|
||||
|
||||
qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
|
||||
qc->scsidone(cmd);
|
||||
ata_qc_free(qc);
|
||||
|
|
|
@ -1106,7 +1106,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->mmio_base = port_base;
|
||||
probe_ent->private_data = hpriv;
|
||||
|
||||
hpriv->host_base = host_base;
|
||||
|
|
|
@ -110,7 +110,6 @@ static void au1xxx_start_ohc(struct platform_device *dev)
|
|||
|
||||
printk(KERN_DEBUG __FILE__
|
||||
": Clock to USB host has been enabled \n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void au1xxx_stop_ohc(struct platform_device *dev)
|
||||
|
|
|
@ -597,9 +597,9 @@ static void atp_disconnect(struct usb_interface *iface)
|
|||
if (dev) {
|
||||
usb_kill_urb(dev->urb);
|
||||
input_unregister_device(dev->input);
|
||||
usb_free_urb(dev->urb);
|
||||
usb_buffer_free(dev->udev, dev->datalen,
|
||||
dev->data, dev->urb->transfer_dma);
|
||||
usb_free_urb(dev->urb);
|
||||
kfree(dev);
|
||||
}
|
||||
printk(KERN_INFO "input: appletouch disconnected\n");
|
||||
|
|
|
@ -111,14 +111,28 @@
|
|||
#define NAME_BUFSIZE 80 /* size of product name, path buffers */
|
||||
#define DATA_BUFSIZE 63 /* size of URB data buffers */
|
||||
|
||||
/*
|
||||
* Duplicate event filtering time.
|
||||
* Sequential, identical KIND_FILTERED inputs with less than
|
||||
* FILTER_TIME milliseconds between them are considered as repeat
|
||||
* events. The hardware generates 5 events for the first keypress
|
||||
* and we have to take this into account for an accurate repeat
|
||||
* behaviour.
|
||||
*/
|
||||
#define FILTER_TIME 60 /* msec */
|
||||
|
||||
static unsigned long channel_mask;
|
||||
module_param(channel_mask, ulong, 0444);
|
||||
module_param(channel_mask, ulong, 0644);
|
||||
MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore");
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0444);
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
|
||||
|
||||
static int repeat_filter = FILTER_TIME;
|
||||
module_param(repeat_filter, int, 0644);
|
||||
MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec");
|
||||
|
||||
#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
|
||||
#undef err
|
||||
#define err(format, arg...) printk(KERN_ERR format , ## arg)
|
||||
|
@ -143,18 +157,6 @@ MODULE_DEVICE_TABLE(usb, ati_remote_table);
|
|||
static char init1[] = { 0x01, 0x00, 0x20, 0x14 };
|
||||
static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
|
||||
|
||||
/* Acceleration curve for directional control pad */
|
||||
static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
|
||||
|
||||
/* Duplicate event filtering time.
|
||||
* Sequential, identical KIND_FILTERED inputs with less than
|
||||
* FILTER_TIME jiffies between them are considered as repeat
|
||||
* events. The hardware generates 5 events for the first keypress
|
||||
* and we have to take this into account for an accurate repeat
|
||||
* behaviour.
|
||||
*/
|
||||
#define FILTER_TIME 60 /* msec */
|
||||
|
||||
struct ati_remote {
|
||||
struct input_dev *idev;
|
||||
struct usb_device *udev;
|
||||
|
@ -411,6 +413,43 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_compute_accel
|
||||
*
|
||||
* Implements acceleration curve for directional control pad
|
||||
* If elapsed time since last event is > 1/4 second, user "stopped",
|
||||
* so reset acceleration. Otherwise, user is probably holding the control
|
||||
* pad down, so we increase acceleration, ramping up over two seconds to
|
||||
* a maximum speed.
|
||||
*/
|
||||
static int ati_remote_compute_accel(struct ati_remote *ati_remote)
|
||||
{
|
||||
static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
|
||||
unsigned long now = jiffies;
|
||||
int acc;
|
||||
|
||||
if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) {
|
||||
acc = 1;
|
||||
ati_remote->acc_jiffies = now;
|
||||
}
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125)))
|
||||
acc = accel[0];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250)))
|
||||
acc = accel[1];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500)))
|
||||
acc = accel[2];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000)))
|
||||
acc = accel[3];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500)))
|
||||
acc = accel[4];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000)))
|
||||
acc = accel[5];
|
||||
else
|
||||
acc = accel[6];
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_report_input
|
||||
*/
|
||||
|
@ -464,9 +503,9 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
|
|||
|
||||
if (ati_remote_tbl[index].kind == KIND_FILTERED) {
|
||||
/* Filter duplicate events which happen "too close" together. */
|
||||
if ((ati_remote->old_data[0] == data[1]) &&
|
||||
(ati_remote->old_data[1] == data[2]) &&
|
||||
time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(FILTER_TIME))) {
|
||||
if (ati_remote->old_data[0] == data[1] &&
|
||||
ati_remote->old_data[1] == data[2] &&
|
||||
time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) {
|
||||
ati_remote->repeat_count++;
|
||||
} else {
|
||||
ati_remote->repeat_count = 0;
|
||||
|
@ -476,75 +515,61 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
|
|||
ati_remote->old_data[1] = data[2];
|
||||
ati_remote->old_jiffies = jiffies;
|
||||
|
||||
if ((ati_remote->repeat_count > 0)
|
||||
&& (ati_remote->repeat_count < 5))
|
||||
if (ati_remote->repeat_count > 0 &&
|
||||
ati_remote->repeat_count < 5)
|
||||
return;
|
||||
|
||||
|
||||
input_regs(dev, regs);
|
||||
input_event(dev, ati_remote_tbl[index].type,
|
||||
ati_remote_tbl[index].code, 1);
|
||||
input_sync(dev);
|
||||
input_event(dev, ati_remote_tbl[index].type,
|
||||
ati_remote_tbl[index].code, 0);
|
||||
input_sync(dev);
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Other event kinds are from the directional control pad, and have an
|
||||
* acceleration factor applied to them. Without this acceleration, the
|
||||
* control pad is mostly unusable.
|
||||
*
|
||||
* If elapsed time since last event is > 1/4 second, user "stopped",
|
||||
* so reset acceleration. Otherwise, user is probably holding the control
|
||||
* pad down, so we increase acceleration, ramping up over two seconds to
|
||||
* a maximum speed. The acceleration curve is #defined above.
|
||||
*/
|
||||
if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) {
|
||||
acc = 1;
|
||||
ati_remote->acc_jiffies = jiffies;
|
||||
}
|
||||
else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0];
|
||||
else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1];
|
||||
else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2];
|
||||
else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3];
|
||||
else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4];
|
||||
else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5];
|
||||
else acc = accel[6];
|
||||
/*
|
||||
* Other event kinds are from the directional control pad, and have an
|
||||
* acceleration factor applied to them. Without this acceleration, the
|
||||
* control pad is mostly unusable.
|
||||
*/
|
||||
acc = ati_remote_compute_accel(ati_remote);
|
||||
|
||||
input_regs(dev, regs);
|
||||
switch (ati_remote_tbl[index].kind) {
|
||||
case KIND_ACCEL:
|
||||
input_event(dev, ati_remote_tbl[index].type,
|
||||
ati_remote_tbl[index].code,
|
||||
ati_remote_tbl[index].value * acc);
|
||||
break;
|
||||
case KIND_LU:
|
||||
input_report_rel(dev, REL_X, -acc);
|
||||
input_report_rel(dev, REL_Y, -acc);
|
||||
break;
|
||||
case KIND_RU:
|
||||
input_report_rel(dev, REL_X, acc);
|
||||
input_report_rel(dev, REL_Y, -acc);
|
||||
break;
|
||||
case KIND_LD:
|
||||
input_report_rel(dev, REL_X, -acc);
|
||||
input_report_rel(dev, REL_Y, acc);
|
||||
break;
|
||||
case KIND_RD:
|
||||
input_report_rel(dev, REL_X, acc);
|
||||
input_report_rel(dev, REL_Y, acc);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
|
||||
ati_remote_tbl[index].kind);
|
||||
}
|
||||
input_sync(dev);
|
||||
input_regs(dev, regs);
|
||||
switch (ati_remote_tbl[index].kind) {
|
||||
case KIND_ACCEL:
|
||||
input_event(dev, ati_remote_tbl[index].type,
|
||||
ati_remote_tbl[index].code,
|
||||
ati_remote_tbl[index].value * acc);
|
||||
break;
|
||||
case KIND_LU:
|
||||
input_report_rel(dev, REL_X, -acc);
|
||||
input_report_rel(dev, REL_Y, -acc);
|
||||
break;
|
||||
case KIND_RU:
|
||||
input_report_rel(dev, REL_X, acc);
|
||||
input_report_rel(dev, REL_Y, -acc);
|
||||
break;
|
||||
case KIND_LD:
|
||||
input_report_rel(dev, REL_X, -acc);
|
||||
input_report_rel(dev, REL_Y, acc);
|
||||
break;
|
||||
case KIND_RD:
|
||||
input_report_rel(dev, REL_X, acc);
|
||||
input_report_rel(dev, REL_Y, acc);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
|
||||
ati_remote_tbl[index].kind);
|
||||
}
|
||||
input_sync(dev);
|
||||
|
||||
ati_remote->old_jiffies = jiffies;
|
||||
ati_remote->old_data[0] = data[1];
|
||||
ati_remote->old_data[1] = data[2];
|
||||
ati_remote->old_jiffies = jiffies;
|
||||
ati_remote->old_data[0] = data[1];
|
||||
ati_remote->old_data[1] = data[2];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -607,7 +607,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|||
|
||||
}
|
||||
|
||||
if (usage->hat_min < usage->hat_max || usage->hat_dir) {
|
||||
if (usage->type == EV_ABS &&
|
||||
(usage->hat_min < usage->hat_max || usage->hat_dir)) {
|
||||
int i;
|
||||
for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
|
||||
input_set_abs_params(input, i, -1, 1, 0, 0);
|
||||
|
|
|
@ -49,7 +49,7 @@ struct hiddev {
|
|||
int open;
|
||||
wait_queue_head_t wait;
|
||||
struct hid_device *hid;
|
||||
struct hiddev_list *list;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct hiddev_list {
|
||||
|
@ -59,7 +59,7 @@ struct hiddev_list {
|
|||
unsigned flags;
|
||||
struct fasync_struct *fasync;
|
||||
struct hiddev *hiddev;
|
||||
struct hiddev_list *next;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
static struct hiddev *hiddev_table[HIDDEV_MINORS];
|
||||
|
@ -73,12 +73,15 @@ static struct hiddev *hiddev_table[HIDDEV_MINORS];
|
|||
static struct hid_report *
|
||||
hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
|
||||
{
|
||||
unsigned flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
|
||||
unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
|
||||
unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK;
|
||||
struct hid_report_enum *report_enum;
|
||||
struct hid_report *report;
|
||||
struct list_head *list;
|
||||
|
||||
if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
|
||||
rinfo->report_type > HID_REPORT_TYPE_MAX) return NULL;
|
||||
rinfo->report_type > HID_REPORT_TYPE_MAX)
|
||||
return NULL;
|
||||
|
||||
report_enum = hid->report_enum +
|
||||
(rinfo->report_type - HID_REPORT_TYPE_MIN);
|
||||
|
@ -88,21 +91,25 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
|
|||
break;
|
||||
|
||||
case HID_REPORT_ID_FIRST:
|
||||
list = report_enum->report_list.next;
|
||||
if (list == &report_enum->report_list)
|
||||
if (list_empty(&report_enum->report_list))
|
||||
return NULL;
|
||||
rinfo->report_id = ((struct hid_report *) list)->id;
|
||||
|
||||
list = report_enum->report_list.next;
|
||||
report = list_entry(list, struct hid_report, list);
|
||||
rinfo->report_id = report->id;
|
||||
break;
|
||||
|
||||
case HID_REPORT_ID_NEXT:
|
||||
list = (struct list_head *)
|
||||
report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK];
|
||||
if (list == NULL)
|
||||
report = report_enum->report_id_hash[rid];
|
||||
if (!report)
|
||||
return NULL;
|
||||
list = list->next;
|
||||
|
||||
list = report->list.next;
|
||||
if (list == &report_enum->report_list)
|
||||
return NULL;
|
||||
rinfo->report_id = ((struct hid_report *) list)->id;
|
||||
|
||||
report = list_entry(list, struct hid_report, list);
|
||||
rinfo->report_id = report->id;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -125,12 +132,13 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
|
|||
struct hid_field *field;
|
||||
|
||||
if (uref->report_type < HID_REPORT_TYPE_MIN ||
|
||||
uref->report_type > HID_REPORT_TYPE_MAX) return NULL;
|
||||
uref->report_type > HID_REPORT_TYPE_MAX)
|
||||
return NULL;
|
||||
|
||||
report_enum = hid->report_enum +
|
||||
(uref->report_type - HID_REPORT_TYPE_MIN);
|
||||
|
||||
list_for_each_entry(report, &report_enum->report_list, list)
|
||||
list_for_each_entry(report, &report_enum->report_list, list) {
|
||||
for (i = 0; i < report->maxfield; i++) {
|
||||
field = report->field[i];
|
||||
for (j = 0; j < field->maxusage; j++) {
|
||||
|
@ -142,6 +150,7 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -150,9 +159,9 @@ static void hiddev_send_event(struct hid_device *hid,
|
|||
struct hiddev_usage_ref *uref)
|
||||
{
|
||||
struct hiddev *hiddev = hid->hiddev;
|
||||
struct hiddev_list *list = hiddev->list;
|
||||
struct hiddev_list *list;
|
||||
|
||||
while (list) {
|
||||
list_for_each_entry(list, &hiddev->list, node) {
|
||||
if (uref->field_index != HID_FIELD_INDEX_NONE ||
|
||||
(list->flags & HIDDEV_FLAG_REPORT) != 0) {
|
||||
list->buffer[list->head] = *uref;
|
||||
|
@ -160,8 +169,6 @@ static void hiddev_send_event(struct hid_device *hid,
|
|||
(HIDDEV_BUFFER_SIZE - 1);
|
||||
kill_fasync(&list->fasync, SIGIO, POLL_IN);
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
wake_up_interruptible(&hiddev->wait);
|
||||
|
@ -180,7 +187,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
|
|||
uref.report_type =
|
||||
(type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
|
||||
((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
|
||||
((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
|
||||
((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
|
||||
uref.report_id = field->report->id;
|
||||
uref.field_index = field->index;
|
||||
uref.usage_index = (usage - field->usage);
|
||||
|
@ -200,7 +207,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
|
|||
uref.report_type =
|
||||
(type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
|
||||
((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
|
||||
((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
|
||||
((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
|
||||
uref.report_id = report->id;
|
||||
uref.field_index = HID_FIELD_INDEX_NONE;
|
||||
|
||||
|
@ -213,7 +220,9 @@ static int hiddev_fasync(int fd, struct file *file, int on)
|
|||
{
|
||||
int retval;
|
||||
struct hiddev_list *list = file->private_data;
|
||||
|
||||
retval = fasync_helper(fd, file, on, &list->fasync);
|
||||
|
||||
return retval < 0 ? retval : 0;
|
||||
}
|
||||
|
||||
|
@ -224,14 +233,9 @@ static int hiddev_fasync(int fd, struct file *file, int on)
|
|||
static int hiddev_release(struct inode * inode, struct file * file)
|
||||
{
|
||||
struct hiddev_list *list = file->private_data;
|
||||
struct hiddev_list **listptr;
|
||||
|
||||
listptr = &list->hiddev->list;
|
||||
hiddev_fasync(-1, file, 0);
|
||||
|
||||
while (*listptr && (*listptr != list))
|
||||
listptr = &((*listptr)->next);
|
||||
*listptr = (*listptr)->next;
|
||||
list_del(&list->node);
|
||||
|
||||
if (!--list->hiddev->open) {
|
||||
if (list->hiddev->exist)
|
||||
|
@ -248,7 +252,8 @@ static int hiddev_release(struct inode * inode, struct file * file)
|
|||
/*
|
||||
* open file op
|
||||
*/
|
||||
static int hiddev_open(struct inode * inode, struct file * file) {
|
||||
static int hiddev_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct hiddev_list *list;
|
||||
|
||||
int i = iminor(inode) - HIDDEV_MINOR_BASE;
|
||||
|
@ -260,9 +265,7 @@ static int hiddev_open(struct inode * inode, struct file * file) {
|
|||
return -ENOMEM;
|
||||
|
||||
list->hiddev = hiddev_table[i];
|
||||
list->next = hiddev_table[i]->list;
|
||||
hiddev_table[i]->list = list;
|
||||
|
||||
list_add_tail(&list->node, &hiddev_table[i]->list);
|
||||
file->private_data = list;
|
||||
|
||||
if (!list->hiddev->open++)
|
||||
|
@ -362,6 +365,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
|
|||
static unsigned int hiddev_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct hiddev_list *list = file->private_data;
|
||||
|
||||
poll_wait(file, &list->hiddev->wait, wait);
|
||||
if (list->head != list->tail)
|
||||
return POLLIN | POLLRDNORM;
|
||||
|
@ -382,7 +386,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
|
|||
struct hiddev_collection_info cinfo;
|
||||
struct hiddev_report_info rinfo;
|
||||
struct hiddev_field_info finfo;
|
||||
struct hiddev_usage_ref_multi *uref_multi=NULL;
|
||||
struct hiddev_usage_ref_multi *uref_multi = NULL;
|
||||
struct hiddev_usage_ref *uref;
|
||||
struct hiddev_devinfo dinfo;
|
||||
struct hid_report *report;
|
||||
|
@ -764,15 +768,15 @@ int hiddev_connect(struct hid_device *hid)
|
|||
}
|
||||
|
||||
init_waitqueue_head(&hiddev->wait);
|
||||
|
||||
hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
|
||||
|
||||
INIT_LIST_HEAD(&hiddev->list);
|
||||
hiddev->hid = hid;
|
||||
hiddev->exist = 1;
|
||||
|
||||
hid->minor = hid->intf->minor;
|
||||
hid->hiddev = hiddev;
|
||||
|
||||
hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1242,11 +1242,12 @@ done:
|
|||
static int ctrl_out (struct usbtest_dev *dev,
|
||||
unsigned count, unsigned length, unsigned vary)
|
||||
{
|
||||
unsigned i, j, len, retval;
|
||||
unsigned i, j, len;
|
||||
int retval;
|
||||
u8 *buf;
|
||||
char *what = "?";
|
||||
struct usb_device *udev;
|
||||
|
||||
|
||||
if (length < 1 || length > 0xffff || vary >= length)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
@ -306,6 +306,8 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
|
|||
|
||||
|
||||
static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
#define FTDI_NF_RIC_PID 0x0001 /* Product Id */
|
||||
|
||||
|
||||
/* www.canusb.com Lawicel CANUSB device */
|
||||
#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */
|
||||
|
||||
/* AlphaMicro Components AMC-232USB01 device */
|
||||
#define FTDI_AMC232_PID 0xFF00 /* Product Id */
|
||||
|
||||
/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */
|
||||
#define FTDI_ACTZWAVE_PID 0xF2D0
|
||||
|
||||
|
|
|
@ -251,6 +251,8 @@ static struct usb_device_id ipaq_id_table [] = {
|
|||
{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
|
||||
{ USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
|
||||
{ USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */
|
||||
{ USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */
|
||||
{ USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */
|
||||
{ USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
|
||||
{ USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
|
||||
{ USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
|
||||
|
|
|
@ -1240,6 +1240,16 @@ UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103,
|
|||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
|
||||
|
||||
/* David Kuehling <dvdkhlng@gmx.de>:
|
||||
* for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI
|
||||
* errors when trying to write.
|
||||
*/
|
||||
UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100,
|
||||
"C-MEX",
|
||||
"A-VOX",
|
||||
US_SC_DEVICE, US_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_RESIDUE ),
|
||||
|
||||
/* Reported by Michael Stattmann <michael@stattmann.com> */
|
||||
UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
|
||||
"Sony Ericsson",
|
||||
|
|
|
@ -1913,9 +1913,6 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
|
|||
u8 chip_rev;
|
||||
u32 dac;
|
||||
|
||||
if (!par->vram_size) /* may have already been probed */
|
||||
par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
|
||||
|
||||
/* Get the chip revision */
|
||||
chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
|
||||
|
||||
|
@ -2028,9 +2025,6 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
|
|||
|
||||
aty128_init_engine(par);
|
||||
|
||||
if (register_framebuffer(info) < 0)
|
||||
return 0;
|
||||
|
||||
par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
|
||||
par->pdev = pdev;
|
||||
par->asleep = 0;
|
||||
|
@ -2040,6 +2034,9 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
|
|||
aty128_bl_init(par);
|
||||
#endif
|
||||
|
||||
if (register_framebuffer(info) < 0)
|
||||
return 0;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
|
||||
info->node, info->fix.id, video_card);
|
||||
|
||||
|
@ -2089,7 +2086,6 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_
|
|||
par = info->par;
|
||||
|
||||
info->pseudo_palette = par->pseudo_palette;
|
||||
info->fix = aty128fb_fix;
|
||||
|
||||
/* Virtualize mmio region */
|
||||
info->fix.mmio_start = reg_addr;
|
||||
|
|
|
@ -156,7 +156,7 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
|
|||
|
||||
info->fix.visual = FB_VISUAL_TRUECOLOR;
|
||||
info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* mono */
|
||||
info->fix.visual = FB_VISUAL_MONO10;
|
||||
|
@ -164,20 +164,16 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
|
|||
}
|
||||
|
||||
info->screen_size = info->fix.line_length * info->var.yres_virtual;
|
||||
info->var.rotate = ((fbdev->panel->control_base&LCD_CONTROL_SM_MASK) \
|
||||
>> LCD_CONTROL_SM_BIT) * 90;
|
||||
|
||||
/* Determine BPP mode and format */
|
||||
fbdev->regs->lcd_control = fbdev->panel->control_base |
|
||||
((info->var.rotate/90) << LCD_CONTROL_SM_BIT);
|
||||
|
||||
fbdev->regs->lcd_control = fbdev->panel->control_base;
|
||||
fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
|
||||
fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
|
||||
fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
|
||||
fbdev->regs->lcd_intenable = 0;
|
||||
fbdev->regs->lcd_intstatus = 0;
|
||||
|
||||
fbdev->regs->lcd_horztiming = fbdev->panel->horztiming;
|
||||
|
||||
fbdev->regs->lcd_verttiming = fbdev->panel->verttiming;
|
||||
|
||||
fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base;
|
||||
|
||||
fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys);
|
||||
|
||||
if (panel_is_dual(fbdev->panel)) {
|
||||
|
@ -206,6 +202,8 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
|
|||
|
||||
/* Resume controller */
|
||||
fbdev->regs->lcd_control |= LCD_CONTROL_GO;
|
||||
mdelay(10);
|
||||
au1100fb_fb_blank(VESA_NO_BLANKING, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -512,7 +512,11 @@ befs_utf2nls(struct super_block *sb, const char *in,
|
|||
wchar_t uni;
|
||||
int unilen, utflen;
|
||||
char *result;
|
||||
int maxlen = in_len; /* The utf8->nls conversion can't make more chars */
|
||||
/* The utf8->nls conversion won't make the final nls string bigger
|
||||
* than the utf one, but if the string is pure ascii they'll have the
|
||||
* same width and an extra char is needed to save the additional \0
|
||||
*/
|
||||
int maxlen = in_len + 1;
|
||||
|
||||
befs_debug(sb, "---> utf2nls()");
|
||||
|
||||
|
@ -588,7 +592,10 @@ befs_nls2utf(struct super_block *sb, const char *in,
|
|||
wchar_t uni;
|
||||
int unilen, utflen;
|
||||
char *result;
|
||||
int maxlen = 3 * in_len;
|
||||
/* There're nls characters that will translate to 3-chars-wide UTF-8
|
||||
* characters, a additional byte is needed to save the final \0
|
||||
* in special cases */
|
||||
int maxlen = (3 * in_len) + 1;
|
||||
|
||||
befs_debug(sb, "---> nls2utf()\n");
|
||||
|
||||
|
|
|
@ -168,16 +168,15 @@ void jfs_dirty_inode(struct inode *inode)
|
|||
set_cflag(COMMIT_Dirty, inode);
|
||||
}
|
||||
|
||||
static int
|
||||
jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
|
||||
struct buffer_head *bh_result, int create)
|
||||
int jfs_get_block(struct inode *ip, sector_t lblock,
|
||||
struct buffer_head *bh_result, int create)
|
||||
{
|
||||
s64 lblock64 = lblock;
|
||||
int rc = 0;
|
||||
xad_t xad;
|
||||
s64 xaddr;
|
||||
int xflag;
|
||||
s32 xlen = max_blocks;
|
||||
s32 xlen = bh_result->b_size >> ip->i_blkbits;
|
||||
|
||||
/*
|
||||
* Take appropriate lock on inode
|
||||
|
@ -188,7 +187,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
|
|||
IREAD_LOCK(ip);
|
||||
|
||||
if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) &&
|
||||
(!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) &&
|
||||
(!xtLookup(ip, lblock64, xlen, &xflag, &xaddr, &xlen, 0)) &&
|
||||
xaddr) {
|
||||
if (xflag & XAD_NOTRECORDED) {
|
||||
if (!create)
|
||||
|
@ -255,13 +254,6 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int jfs_get_block(struct inode *ip, sector_t lblock,
|
||||
struct buffer_head *bh_result, int create)
|
||||
{
|
||||
return jfs_get_blocks(ip, lblock, bh_result->b_size >> ip->i_blkbits,
|
||||
bh_result, create);
|
||||
}
|
||||
|
||||
static int jfs_writepage(struct page *page, struct writeback_control *wbc)
|
||||
{
|
||||
return nobh_writepage(page, jfs_get_block, wbc);
|
||||
|
|
|
@ -32,6 +32,7 @@ extern void jfs_truncate_nolock(struct inode *, loff_t);
|
|||
extern void jfs_free_zero_link(struct inode *);
|
||||
extern struct dentry *jfs_get_parent(struct dentry *dentry);
|
||||
extern void jfs_set_inode_flags(struct inode *);
|
||||
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
||||
|
||||
extern const struct address_space_operations jfs_aops;
|
||||
extern struct inode_operations jfs_dir_inode_operations;
|
||||
|
|
118
fs/jfs/super.c
118
fs/jfs/super.c
|
@ -26,6 +26,7 @@
|
|||
#include <linux/moduleparam.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/posix_acl.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
|
@ -298,7 +299,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
|
|||
break;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_QUOTA)
|
||||
#ifdef CONFIG_QUOTA
|
||||
case Opt_quota:
|
||||
case Opt_usrquota:
|
||||
*flag |= JFS_USRQUOTA;
|
||||
|
@ -597,7 +598,7 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
|
|||
if (sbi->flag & JFS_NOINTEGRITY)
|
||||
seq_puts(seq, ",nointegrity");
|
||||
|
||||
#if defined(CONFIG_QUOTA)
|
||||
#ifdef CONFIG_QUOTA
|
||||
if (sbi->flag & JFS_USRQUOTA)
|
||||
seq_puts(seq, ",usrquota");
|
||||
|
||||
|
@ -608,6 +609,113 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QUOTA
|
||||
|
||||
/* Read data from quotafile - avoid pagecache and such because we cannot afford
|
||||
* acquiring the locks... As quota files are never truncated and quota code
|
||||
* itself serializes the operations (and noone else should touch the files)
|
||||
* we don't have to be afraid of races */
|
||||
static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data,
|
||||
size_t len, loff_t off)
|
||||
{
|
||||
struct inode *inode = sb_dqopt(sb)->files[type];
|
||||
sector_t blk = off >> sb->s_blocksize_bits;
|
||||
int err = 0;
|
||||
int offset = off & (sb->s_blocksize - 1);
|
||||
int tocopy;
|
||||
size_t toread;
|
||||
struct buffer_head tmp_bh;
|
||||
struct buffer_head *bh;
|
||||
loff_t i_size = i_size_read(inode);
|
||||
|
||||
if (off > i_size)
|
||||
return 0;
|
||||
if (off+len > i_size)
|
||||
len = i_size-off;
|
||||
toread = len;
|
||||
while (toread > 0) {
|
||||
tocopy = sb->s_blocksize - offset < toread ?
|
||||
sb->s_blocksize - offset : toread;
|
||||
|
||||
tmp_bh.b_state = 0;
|
||||
tmp_bh.b_size = 1 << inode->i_blkbits;
|
||||
err = jfs_get_block(inode, blk, &tmp_bh, 0);
|
||||
if (err)
|
||||
return err;
|
||||
if (!buffer_mapped(&tmp_bh)) /* A hole? */
|
||||
memset(data, 0, tocopy);
|
||||
else {
|
||||
bh = sb_bread(sb, tmp_bh.b_blocknr);
|
||||
if (!bh)
|
||||
return -EIO;
|
||||
memcpy(data, bh->b_data+offset, tocopy);
|
||||
brelse(bh);
|
||||
}
|
||||
offset = 0;
|
||||
toread -= tocopy;
|
||||
data += tocopy;
|
||||
blk++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Write to quotafile */
|
||||
static ssize_t jfs_quota_write(struct super_block *sb, int type,
|
||||
const char *data, size_t len, loff_t off)
|
||||
{
|
||||
struct inode *inode = sb_dqopt(sb)->files[type];
|
||||
sector_t blk = off >> sb->s_blocksize_bits;
|
||||
int err = 0;
|
||||
int offset = off & (sb->s_blocksize - 1);
|
||||
int tocopy;
|
||||
size_t towrite = len;
|
||||
struct buffer_head tmp_bh;
|
||||
struct buffer_head *bh;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
while (towrite > 0) {
|
||||
tocopy = sb->s_blocksize - offset < towrite ?
|
||||
sb->s_blocksize - offset : towrite;
|
||||
|
||||
tmp_bh.b_state = 0;
|
||||
tmp_bh.b_size = 1 << inode->i_blkbits;
|
||||
err = jfs_get_block(inode, blk, &tmp_bh, 1);
|
||||
if (err)
|
||||
goto out;
|
||||
if (offset || tocopy != sb->s_blocksize)
|
||||
bh = sb_bread(sb, tmp_bh.b_blocknr);
|
||||
else
|
||||
bh = sb_getblk(sb, tmp_bh.b_blocknr);
|
||||
if (!bh) {
|
||||
err = -EIO;
|
||||
goto out;
|
||||
}
|
||||
lock_buffer(bh);
|
||||
memcpy(bh->b_data+offset, data, tocopy);
|
||||
flush_dcache_page(bh->b_page);
|
||||
set_buffer_uptodate(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
unlock_buffer(bh);
|
||||
brelse(bh);
|
||||
offset = 0;
|
||||
towrite -= tocopy;
|
||||
data += tocopy;
|
||||
blk++;
|
||||
}
|
||||
out:
|
||||
if (len == towrite)
|
||||
return err;
|
||||
if (inode->i_size < off+len-towrite)
|
||||
i_size_write(inode, off+len-towrite);
|
||||
inode->i_version++;
|
||||
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
mark_inode_dirty(inode);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return len - towrite;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static struct super_operations jfs_super_operations = {
|
||||
.alloc_inode = jfs_alloc_inode,
|
||||
.destroy_inode = jfs_destroy_inode,
|
||||
|
@ -621,7 +729,11 @@ static struct super_operations jfs_super_operations = {
|
|||
.unlockfs = jfs_unlockfs,
|
||||
.statfs = jfs_statfs,
|
||||
.remount_fs = jfs_remount,
|
||||
.show_options = jfs_show_options
|
||||
.show_options = jfs_show_options,
|
||||
#ifdef CONFIG_QUOTA
|
||||
.quota_read = jfs_quota_read,
|
||||
.quota_write = jfs_quota_write,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct export_operations jfs_export_operations = {
|
||||
|
|
|
@ -638,9 +638,6 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
|
|||
if (task->tk_status < 0) {
|
||||
/* RPC error: Re-insert for retransmission */
|
||||
timeout = 10 * HZ;
|
||||
} else if (block->b_done) {
|
||||
/* Block already removed, kill it for real */
|
||||
timeout = 0;
|
||||
} else {
|
||||
/* Call was successful, now wait for client callback */
|
||||
timeout = 60 * HZ;
|
||||
|
@ -709,13 +706,10 @@ nlmsvc_retry_blocked(void)
|
|||
break;
|
||||
if (time_after(block->b_when,jiffies))
|
||||
break;
|
||||
dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n",
|
||||
block, block->b_when, block->b_done);
|
||||
dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
|
||||
block, block->b_when);
|
||||
kref_get(&block->b_count);
|
||||
if (block->b_done)
|
||||
nlmsvc_unlink_block(block);
|
||||
else
|
||||
nlmsvc_grant_blocked(block);
|
||||
nlmsvc_grant_blocked(block);
|
||||
nlmsvc_release_block(block);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ char *nfs_path(const char *base, const struct dentry *dentry,
|
|||
namelen = dentry->d_name.len;
|
||||
buflen -= namelen + 1;
|
||||
if (buflen < 0)
|
||||
goto Elong;
|
||||
goto Elong_unlock;
|
||||
end -= namelen;
|
||||
memcpy(end, dentry->d_name.name, namelen);
|
||||
*--end = '/';
|
||||
|
@ -68,6 +68,8 @@ char *nfs_path(const char *base, const struct dentry *dentry,
|
|||
end -= namelen;
|
||||
memcpy(end, base, namelen);
|
||||
return end;
|
||||
Elong_unlock:
|
||||
spin_unlock(&dcache_lock);
|
||||
Elong:
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
|
|||
return p;
|
||||
}
|
||||
|
||||
void nfs_readdata_free(struct nfs_read_data *p)
|
||||
static void nfs_readdata_free(struct nfs_read_data *p)
|
||||
{
|
||||
if (p && (p->pagevec != &p->page_array[0]))
|
||||
kfree(p->pagevec);
|
||||
|
|
|
@ -137,7 +137,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
|
|||
return p;
|
||||
}
|
||||
|
||||
void nfs_writedata_free(struct nfs_write_data *p)
|
||||
static void nfs_writedata_free(struct nfs_write_data *p)
|
||||
{
|
||||
if (p && (p->pagevec != &p->page_array[0]))
|
||||
kfree(p->pagevec);
|
||||
|
|
|
@ -48,8 +48,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
reiserfs_write_lock(inode->i_sb);
|
||||
mutex_lock(&inode->i_mutex);
|
||||
reiserfs_write_lock(inode->i_sb);
|
||||
/* freeing preallocation only involves relogging blocks that
|
||||
* are already in the current transaction. preallocation gets
|
||||
* freed at the end of each transaction, so it is impossible for
|
||||
|
|
|
@ -39,14 +39,10 @@ void reiserfs_delete_inode(struct inode *inode)
|
|||
|
||||
/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
|
||||
if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
|
||||
mutex_lock(&inode->i_mutex);
|
||||
|
||||
reiserfs_delete_xattrs(inode);
|
||||
|
||||
if (journal_begin(&th, inode->i_sb, jbegin_count)) {
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (journal_begin(&th, inode->i_sb, jbegin_count))
|
||||
goto out;
|
||||
}
|
||||
reiserfs_update_inode_transaction(inode);
|
||||
|
||||
err = reiserfs_delete_object(&th, inode);
|
||||
|
@ -57,12 +53,8 @@ void reiserfs_delete_inode(struct inode *inode)
|
|||
if (!err)
|
||||
DQUOT_FREE_INODE(inode);
|
||||
|
||||
if (journal_end(&th, inode->i_sb, jbegin_count)) {
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (journal_end(&th, inode->i_sb, jbegin_count))
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
/* check return value from reiserfs_delete_object after
|
||||
* ending the transaction
|
||||
|
@ -2348,6 +2340,7 @@ static int reiserfs_write_full_page(struct page *page,
|
|||
unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
|
||||
int error = 0;
|
||||
unsigned long block;
|
||||
sector_t last_block;
|
||||
struct buffer_head *head, *bh;
|
||||
int partial = 0;
|
||||
int nr = 0;
|
||||
|
@ -2395,10 +2388,19 @@ static int reiserfs_write_full_page(struct page *page,
|
|||
}
|
||||
bh = head;
|
||||
block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits);
|
||||
last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
|
||||
/* first map all the buffers, logging any direct items we find */
|
||||
do {
|
||||
if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
|
||||
(buffer_mapped(bh)
|
||||
if (block > last_block) {
|
||||
/*
|
||||
* This can happen when the block size is less than
|
||||
* the page size. The corresponding bytes in the page
|
||||
* were zero filled above
|
||||
*/
|
||||
clear_buffer_dirty(bh);
|
||||
set_buffer_uptodate(bh);
|
||||
} else if ((checked || buffer_dirty(bh)) &&
|
||||
(!buffer_mapped(bh) || (buffer_mapped(bh)
|
||||
&& bh->b_blocknr ==
|
||||
0))) {
|
||||
/* not mapped yet, or it points to a direct item, search
|
||||
|
|
|
@ -116,12 +116,12 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp)
|
|||
if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
|
||||
return 0;
|
||||
}
|
||||
reiserfs_write_lock(inode->i_sb);
|
||||
|
||||
/* we need to make sure nobody is changing the file size beneath
|
||||
** us
|
||||
*/
|
||||
mutex_lock(&inode->i_mutex);
|
||||
reiserfs_write_lock(inode->i_sb);
|
||||
|
||||
write_from = inode->i_size & (blocksize - 1);
|
||||
/* if we are on a block boundary, we are already unpacked. */
|
||||
|
|
|
@ -75,6 +75,12 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
|
|||
}
|
||||
*err = -ENOSPC;
|
||||
|
||||
UDF_I_UNIQUE(inode) = 0;
|
||||
UDF_I_LENEXTENTS(inode) = 0;
|
||||
UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
|
||||
UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
|
||||
UDF_I_STRAT4096(inode) = 0;
|
||||
|
||||
block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
|
||||
start, err);
|
||||
if (*err)
|
||||
|
@ -84,11 +90,6 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
|
|||
}
|
||||
|
||||
mutex_lock(&sbi->s_alloc_mutex);
|
||||
UDF_I_UNIQUE(inode) = 0;
|
||||
UDF_I_LENEXTENTS(inode) = 0;
|
||||
UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
|
||||
UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
|
||||
UDF_I_STRAT4096(inode) = 0;
|
||||
if (UDF_SB_LVIDBH(sb))
|
||||
{
|
||||
struct logicalVolHeaderDesc *lvhd;
|
||||
|
|
|
@ -248,7 +248,7 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk,
|
|||
|
||||
if (likely(cur_index != index)) {
|
||||
page = ufs_get_locked_page(mapping, index);
|
||||
if (IS_ERR(page))
|
||||
if (!page || IS_ERR(page)) /* it was truncated or EIO */
|
||||
continue;
|
||||
} else
|
||||
page = locked_page;
|
||||
|
|
|
@ -251,12 +251,12 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
|
|||
{
|
||||
struct page *page;
|
||||
|
||||
try_again:
|
||||
page = find_lock_page(mapping, index);
|
||||
if (!page) {
|
||||
page = read_cache_page(mapping, index,
|
||||
(filler_t*)mapping->a_ops->readpage,
|
||||
NULL);
|
||||
|
||||
if (IS_ERR(page)) {
|
||||
printk(KERN_ERR "ufs_change_blocknr: "
|
||||
"read_cache_page error: ino %lu, index: %lu\n",
|
||||
|
@ -266,6 +266,14 @@ try_again:
|
|||
|
||||
lock_page(page);
|
||||
|
||||
if (unlikely(page->mapping == NULL)) {
|
||||
/* Truncate got there first */
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
page = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!PageUptodate(page) || PageError(page)) {
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
|
@ -275,15 +283,8 @@ try_again:
|
|||
mapping->host->i_ino, index);
|
||||
|
||||
page = ERR_PTR(-EIO);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(!page->mapping || !page_has_buffers(page))) {
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
goto try_again;/*we really need these buffers*/
|
||||
}
|
||||
out:
|
||||
return page;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue