Commit 63a84559 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-acpi.bkbits.net/linux-acpi

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 0b32ad59 dccb90df
...@@ -87,7 +87,8 @@ PowerNow! K6: ...@@ -87,7 +87,8 @@ PowerNow! K6:
Transmeta Crusoe Longrun: Transmeta Crusoe Longrun:
Transmeta Crusoe processors: Transmeta Crusoe processors:
-------------------------------- --------------------------------
Does not work with the 2.4. /proc/sys/cpu/ interface. It is recommended to use the 2.6. /proc/cpufreq interface when
using this driver
...@@ -283,15 +284,17 @@ entries: ...@@ -283,15 +284,17 @@ entries:
cpufreq_verify_t verify: This is a pointer to a function with the cpufreq_verify_t verify: This is a pointer to a function with the
following definition: following definition:
void verify_function (struct cpufreq_policy *policy). int verify_function (struct cpufreq_policy *policy).
This function must verify the new policy is within the limits This function must verify the new policy is within the limits
supported by the CPU, and at least one supported CPU is within supported by the CPU, and at least one supported CPU is within
this range. It may be useful to use cpufreq.h / this range. It may be useful to use cpufreq.h /
cpufreq_verify_within_limits for this. cpufreq_verify_within_limits for this. If this is called with
CPUFREQ_ALL_CPUS, and there is no common subset of frequencies
for all CPUs, exit with an error.
cpufreq_setpolicy_t setpolicy: This is a pointer to a function with cpufreq_setpolicy_t setpolicy: This is a pointer to a function with
the following definition: the following definition:
void setpolicy_function (struct cpufreq_policy *policy). int setpolicy_function (struct cpufreq_policy *policy).
This function must set the CPU to the new policy. If it is a This function must set the CPU to the new policy. If it is a
"dumb" CPU which only allows fixed frequencies to be set, it "dumb" CPU which only allows fixed frequencies to be set, it
shall set it to the lowest within the limit for shall set it to the lowest within the limit for
...@@ -302,30 +305,30 @@ cpufreq_setpolicy_t setpolicy: This is a pointer to a function with ...@@ -302,30 +305,30 @@ cpufreq_setpolicy_t setpolicy: This is a pointer to a function with
struct cpufreq_policy *policy: This is an array of NR_CPUS struct struct cpufreq_policy *policy: This is an array of NR_CPUS struct
cpufreq_policies, containing the current policies set for these cpufreq_policies, containing the current policies set for these
CPUs. Note that policy[0].max_cpu_freq must contain the CPUs. Note that policy[cpu].max_cpu_freq must contain the
absolute maximum CPU frequency supported by _all_ CPUs. absolute maximum CPU frequency supported by the specified cpu.
In case the driver is expected to run with the 2.4.-style API In case the driver is expected to run with the 2.4.-style API
(/proc/sys/cpu/.../), two more values must be passed (/proc/sys/cpu/.../), two more values must be passed
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
unsigned int cpu_min_freq; unsigned int cpu_min_freq[NR_CPUS];
unsigned int cpu_cur_freq[NR_CPUS]; unsigned int cpu_cur_freq[NR_CPUS];
#endif #endif
with cpu_min_freq being the minimum CPU frequency supported by with cpu_min_freq[cpu] being the minimum CPU frequency
the CPUs; and the entries in cpu_cur_freq reflecting the supported by the CPU; and the entries in cpu_cur_freq
current speed of the appropriate CPU. reflecting the current speed of the appropriate CPU.
Some Requirements to CPUFreq architecture drivers Some Requirements to CPUFreq architecture drivers
------------------------------------------------- -------------------------------------------------
* Only call cpufreq_register() when the ability to switch CPU * Only call cpufreq_register() when the ability to switch CPU
frequencies is _verified_ or can't be missing frequencies is _verified_ or can't be missing. Also, all
other initialization must be done beofre this call, as
cpfureq_register calls the driver's verify and setpolicy code for
each CPU.
* cpufreq_unregister() may only be called if cpufreq_register() has * cpufreq_unregister() may only be called if cpufreq_register() has
been successfully(!) called before. been successfully(!) called before.
* kfree() the struct cpufreq_driver only after the call to * kfree() the struct cpufreq_driver only after the call to
cpufreq_unregister(), unless cpufreq_register() failed. cpufreq_unregister(), unless cpufreq_register() failed.
* Be aware that there is currently no error management in the
setpolicy() code in the CPUFreq core. So only call yourself a
cpufreq_driver if you are really a working cpufreq_driver!
......
Sony Programmable I/O Control Device Driver Readme Sony Programmable I/O Control Device Driver Readme
-------------------------------------------------- --------------------------------------------------
Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
Copyright (C) 2001-2002 Alcôve <www.alcove.com>
Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp> Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp> Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
...@@ -15,14 +16,14 @@ generate, like: ...@@ -15,14 +16,14 @@ generate, like:
- capture button events (only on Vaio Picturebook series) - capture button events (only on Vaio Picturebook series)
- Fn keys - Fn keys
- bluetooth button (only on C1VR model) - bluetooth button (only on C1VR model)
- back button (PCG-GR7/K model) - programmable keys, back, help, zoom, thumbphrase buttons, etc.
- lid open/close events (Z600NE model) (when available)
Those events (see linux/sonypi.h) can be polled using the character device node Those events (see linux/sonypi.h) can be polled using the character device node
/dev/sonypi (major 10, minor auto allocated or specified as a option). /dev/sonypi (major 10, minor auto allocated or specified as a option).
A simple daemon which translates the jogdial movements into mouse wheel events A simple daemon which translates the jogdial movements into mouse wheel events
can be downloaded at: <http://www.alcove-labs.org/en/software/sonypi/> can be downloaded at: <http://popies.net/sonypi/>
This driver supports also some ioctl commands for setting the LCD screen This driver supports also some ioctl commands for setting the LCD screen
brightness and querying the batteries charge information (some more brightness and querying the batteries charge information (some more
...@@ -43,7 +44,7 @@ Several options can be passed to the sonypi driver, either by adding them ...@@ -43,7 +44,7 @@ Several options can be passed to the sonypi driver, either by adding them
to /etc/modules.conf file, when the driver is compiled as a module or by to /etc/modules.conf file, when the driver is compiled as a module or by
adding the following to the kernel command line (in your bootloader): adding the following to the kernel command line (in your bootloader):
sonypi=minor[,verbose[,fnkeyinit[,camera[,compat[,nojogdial]]]]] sonypi=minor[,verbose[,fnkeyinit[,camera[,compat[,mask]]]]]
where: where:
...@@ -64,15 +65,36 @@ where: ...@@ -64,15 +65,36 @@ where:
with it and it shouldn't be required anyway if with it and it shouldn't be required anyway if
ACPI is already enabled). ACPI is already enabled).
verbose: print unknown events from the sonypi device verbose: set to 1 to print unknown events received from the
sonypi device.
set to 2 to print all events received from the
sonypi device.
compat: uses some compatibility code for enabling the sonypi compat: uses some compatibility code for enabling the sonypi
events. If the driver worked for you in the past events. If the driver worked for you in the past
(prior to version 1.5) and does not work anymore, (prior to version 1.5) and does not work anymore,
add this option and report to the author. add this option and report to the author.
nojogdial: gives more accurate PKEY events on those Vaio models mask: event mask telling the driver what events will be
which don't have a jogdial (like the FX series). reported to the user. This parameter is required for some
Vaio models where the hardware reuses values used in
other Vaio models (like the FX series who does not
have a jogdial but reuses the jogdial events for
programmable keys events). The default event mask is
set to 0xffffffff, meaning that all possible events will be
tried. You can use the following bits to construct
your own event mask (from drivers/char/sonypi.h):
SONYPI_JOGGER_MASK 0x0001
SONYPI_CAPTURE_MASK 0x0002
SONYPI_FNKEY_MASK 0x0004
SONYPI_BLUETOOTH_MASK 0x0008
SONYPI_PKEY_MASK 0x0010
SONYPI_BACK_MASK 0x0020
SONYPI_HELP_MASK 0x0040
SONYPI_LID_MASK 0x0080
SONYPI_ZOOM_MASK 0x0100
SONYPI_THUMBPHRASE_MASK 0x0200
SONYPI_MEYE_MASK 0x0400
Module use: Module use:
----------- -----------
......
Vaio Picturebook Motion Eye Camera Driver Readme Vaio Picturebook Motion Eye Camera Driver Readme
------------------------------------------------ ------------------------------------------------
Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
Copyright (C) 2001-2002 Alcôve <www.alcove.com>
Copyright (C) 2000 Andrew Tridgell <tridge@samba.org> Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
This driver enable the use of video4linux compatible applications with the This driver enable the use of video4linux compatible applications with the
...@@ -52,7 +53,7 @@ Usage: ...@@ -52,7 +53,7 @@ Usage:
or or
xawtv -c /dev/video0 -geometry 320x240 xawtv -c /dev/video0 -geometry 320x240
motioneye (<http://www.alcove-labs.org/en/software/meye/>) motioneye (<http://popies.net/meye/>)
for getting ppm or jpg snapshots, mjpeg video for getting ppm or jpg snapshots, mjpeg video
Private API: Private API:
......
...@@ -73,7 +73,7 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor) ...@@ -73,7 +73,7 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor)
* Validate the speed in khz. If it is outside our * Validate the speed in khz. If it is outside our
* range, then return the lowest. * range, then return the lowest.
*/ */
static void integrator_verify_speed(struct cpufreq_policy *policy) static int integrator_verify_speed(struct cpufreq_policy *policy)
{ {
struct vco vco; struct vco vco;
...@@ -93,6 +93,8 @@ static void integrator_verify_speed(struct cpufreq_policy *policy) ...@@ -93,6 +93,8 @@ static void integrator_verify_speed(struct cpufreq_policy *policy)
vco.vdw = 152; vco.vdw = 152;
policy->min = policy->max = vco_to_freq(vco, 1); policy->min = policy->max = vco_to_freq(vco, 1);
return 0;
} }
static void do_set_policy(int cpu, struct cpufreq_policy *policy) static void do_set_policy(int cpu, struct cpufreq_policy *policy)
...@@ -116,7 +118,7 @@ static void do_set_policy(int cpu, struct cpufreq_policy *policy) ...@@ -116,7 +118,7 @@ static void do_set_policy(int cpu, struct cpufreq_policy *policy)
__raw_writel(0, CM_LOCK); __raw_writel(0, CM_LOCK);
} }
static void integrator_set_policy(struct cpufreq_policy *policy) static int integrator_set_policy(struct cpufreq_policy *policy)
{ {
unsigned long cpus_allowed; unsigned long cpus_allowed;
int cpu; int cpu;
...@@ -139,6 +141,8 @@ static void integrator_set_policy(struct cpufreq_policy *policy) ...@@ -139,6 +141,8 @@ static void integrator_set_policy(struct cpufreq_policy *policy)
* Restore the CPUs allowed mask. * Restore the CPUs allowed mask.
*/ */
set_cpus_allowed(current, cpus_allowed); set_cpus_allowed(current, cpus_allowed);
return 0;
} }
static struct cpufreq_policy integrator_policy = { static struct cpufreq_policy integrator_policy = {
...@@ -151,7 +155,6 @@ static struct cpufreq_driver integrator_driver = { ...@@ -151,7 +155,6 @@ static struct cpufreq_driver integrator_driver = {
.verify = integrator_verify_speed, .verify = integrator_verify_speed,
.setpolicy = integrator_set_policy, .setpolicy = integrator_set_policy,
.policy = &integrator_policy, .policy = &integrator_policy,
.cpu_min_freq = 12000,
}; };
#endif #endif
...@@ -202,6 +205,8 @@ static int __init integrator_cpu_init(void) ...@@ -202,6 +205,8 @@ static int __init integrator_cpu_init(void)
set_cpus_allowed(current, cpus_allowed); set_cpus_allowed(current, cpus_allowed);
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
for (cpu=0; cpu<NR_CPUS; cpu++)
integrator_driver.cpu_min_freq[cpu] = 12000;
integrator_driver.policy = policies; integrator_driver.policy = policies;
cpufreq_register(&integrator_driver); cpufreq_register(&integrator_driver);
#else #else
......
...@@ -176,7 +176,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed) ...@@ -176,7 +176,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
} }
} }
static void sa1100_setspeed(struct cpufreq_policy *policy) static int sa1100_setspeed(struct cpufreq_policy *policy)
{ {
unsigned int cur = sa11x0_getspeed(); unsigned int cur = sa11x0_getspeed();
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
...@@ -196,6 +196,8 @@ static void sa1100_setspeed(struct cpufreq_policy *policy) ...@@ -196,6 +196,8 @@ static void sa1100_setspeed(struct cpufreq_policy *policy)
sa1100_update_dram_timings(cur, policy->max); sa1100_update_dram_timings(cur, policy->max);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
} }
static struct cpufreq_policy sa1100_policy = { static struct cpufreq_policy sa1100_policy = {
...@@ -208,7 +210,7 @@ static struct cpufreq_driver sa1100_driver = { ...@@ -208,7 +210,7 @@ static struct cpufreq_driver sa1100_driver = {
.verify = sa11x0_verify_speed, .verify = sa11x0_verify_speed,
.setpolicy = sa1100_setspeed, .setpolicy = sa1100_setspeed,
.policy = &sa1100_policy, .policy = &sa1100_policy,
.cpu_min_freq = 59000, .cpu_min_freq[0]= 59000,
}; };
static int __init sa1100_dram_init(void) static int __init sa1100_dram_init(void)
...@@ -216,7 +218,7 @@ static int __init sa1100_dram_init(void) ...@@ -216,7 +218,7 @@ static int __init sa1100_dram_init(void)
int ret = -ENODEV; int ret = -ENODEV;
if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) { if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
sa1100_driver.cpu_curr_freq[0] = sa1100_driver.cpu_cur_freq[0] =
sa1100_policy.min = sa1100_policy.min =
sa1100_policy.max = sa11x0_getspeed(); sa1100_policy.max = sa11x0_getspeed();
......
...@@ -212,7 +212,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) ...@@ -212,7 +212,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
* above, we can match for an exact frequency. If we don't find * above, we can match for an exact frequency. If we don't find
* an exact match, we will to set the lowest frequency to be safe. * an exact match, we will to set the lowest frequency to be safe.
*/ */
static void sa1110_setspeed(struct cpufreq_policy *policy) static int sa1110_setspeed(struct cpufreq_policy *policy)
{ {
struct sdram_params *sdram = &sdram_params; struct sdram_params *sdram = &sdram_params;
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
...@@ -291,6 +291,8 @@ static void sa1110_setspeed(struct cpufreq_policy *policy) ...@@ -291,6 +291,8 @@ static void sa1110_setspeed(struct cpufreq_policy *policy)
sdram_update_refresh(policy->max, sdram); sdram_update_refresh(policy->max, sdram);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
} }
static struct cpufreq_policy sa1110_policy = { static struct cpufreq_policy sa1110_policy = {
...@@ -300,10 +302,10 @@ static struct cpufreq_policy sa1110_policy = { ...@@ -300,10 +302,10 @@ static struct cpufreq_policy sa1110_policy = {
}; };
static struct cpufreq_driver sa1110_driver = { static struct cpufreq_driver sa1110_driver = {
.verify = sa11x0_verify_speed, .verify = sa11x0_verify_speed,
.setpolicy = sa1110_setspeed, .setpolicy = sa1110_setspeed,
.policy = &sa1110_policy, .policy = &sa1110_policy,
.cpu_min_freq = 59000, .cpu_min_freq[0] = 59000,
}; };
static int __init sa1110_clk_init(void) static int __init sa1110_clk_init(void)
......
...@@ -67,7 +67,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz) ...@@ -67,7 +67,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
* scaling, so we force min=max, and set the policy to "performance". * scaling, so we force min=max, and set the policy to "performance".
* If we can't generate the precise frequency requested, round it up. * If we can't generate the precise frequency requested, round it up.
*/ */
void sa11x0_verify_speed(struct cpufreq_policy *policy) int sa11x0_verify_speed(struct cpufreq_policy *policy)
{ {
if (policy->max > policy->max_cpu_freq) if (policy->max > policy->max_cpu_freq)
policy->max = policy->max_cpu_freq; policy->max = policy->max_cpu_freq;
...@@ -75,6 +75,7 @@ void sa11x0_verify_speed(struct cpufreq_policy *policy) ...@@ -75,6 +75,7 @@ void sa11x0_verify_speed(struct cpufreq_policy *policy)
policy->max = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->max)] * 100; policy->max = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->max)] * 100;
policy->min = policy->max; policy->min = policy->max;
policy->policy = CPUFREQ_POLICY_POWERSAVE; policy->policy = CPUFREQ_POLICY_POWERSAVE;
return 0;
} }
unsigned int sa11x0_getspeed(void) unsigned int sa11x0_getspeed(void)
......
...@@ -172,13 +172,13 @@ static void elanfreq_set_cpu_state (unsigned int state) { ...@@ -172,13 +172,13 @@ static void elanfreq_set_cpu_state (unsigned int state) {
* for the hardware supported by the driver. * for the hardware supported by the driver.
*/ */
static void elanfreq_verify (struct cpufreq_policy *policy) static int elanfreq_verify (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
if (!policy || !max_freq) if (!policy || !max_freq)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
...@@ -190,7 +190,7 @@ static void elanfreq_verify (struct cpufreq_policy *policy) ...@@ -190,7 +190,7 @@ static void elanfreq_verify (struct cpufreq_policy *policy)
number_states++; number_states++;
if (number_states) if (number_states)
return; return 0;
for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--) for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--)
if (elan_multiplier[i].clock < policy->max) if (elan_multiplier[i].clock < policy->max)
...@@ -198,16 +198,16 @@ static void elanfreq_verify (struct cpufreq_policy *policy) ...@@ -198,16 +198,16 @@ static void elanfreq_verify (struct cpufreq_policy *policy)
policy->max = elan_multiplier[i+1].clock; policy->max = elan_multiplier[i+1].clock;
return; return 0;
} }
static void elanfreq_setpolicy (struct cpufreq_policy *policy) static int elanfreq_setpolicy (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i, j=4; unsigned int i, j=4;
if (!elanfreq_driver) if (!elanfreq_driver)
return; return -EINVAL;
for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--) for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--)
if ((elan_multiplier[i].clock >= policy->min) && if ((elan_multiplier[i].clock >= policy->min) &&
...@@ -219,7 +219,7 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy) ...@@ -219,7 +219,7 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy)
if (number_states == 1) { if (number_states == 1) {
elanfreq_set_cpu_state(j); elanfreq_set_cpu_state(j);
return; return 0;
} }
switch (policy->policy) { switch (policy->policy) {
...@@ -236,14 +236,14 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy) ...@@ -236,14 +236,14 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy)
j = i; j = i;
break; break;
default: default:
return; return -EINVAL;
} }
if (elan_multiplier[j].clock > max_freq) if (elan_multiplier[j].clock > max_freq)
BUG(); return -EINVAL;
elanfreq_set_cpu_state(j); elanfreq_set_cpu_state(j);
return; return 0;
} }
...@@ -296,7 +296,7 @@ static int __init elanfreq_init(void) ...@@ -296,7 +296,7 @@ static int __init elanfreq_init(void)
max_freq = elanfreq_get_cpu_frequency(); max_freq = elanfreq_get_cpu_frequency();
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = 1000; driver->cpu_min_freq[0] = 1000;
driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency(); driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency();
#endif #endif
...@@ -309,15 +309,15 @@ static int __init elanfreq_init(void) ...@@ -309,15 +309,15 @@ static int __init elanfreq_init(void)
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].max_cpu_freq = max_freq; driver->policy[0].max_cpu_freq = max_freq;
elanfreq_driver = driver;
ret = cpufreq_register(driver); ret = cpufreq_register(driver);
if (ret) { if (ret) {
elanfreq_driver = NULL;
kfree(driver); kfree(driver);
return ret;
} }
elanfreq_driver = driver; return ret;
return 0;
} }
......
/* /*
* $Id: longhaul.c,v 1.72 2002/09/29 23:43:10 db Exp $ * $Id: longhaul.c,v 1.77 2002/10/31 21:17:40 db Exp $
* *
* (C) 2001 Dave Jones. <davej@suse.de> * (C) 2001 Dave Jones. <davej@suse.de>
* (C) 2002 Padraig Brady. <padraig@antefacto.com> * (C) 2002 Padraig Brady. <padraig@antefacto.com>
...@@ -436,8 +436,10 @@ static void __init longhaul_get_ranges (void) ...@@ -436,8 +436,10 @@ static void __init longhaul_get_ranges (void)
switch (longhaul) { switch (longhaul) {
case 1: case 1:
/* Ugh, Longhaul v1 didn't have the min/max MSRs. /* Ugh, Longhaul v1 didn't have the min/max MSRs.
Assume max = whatever we booted at. */ Assume min=3.0x & max = whatever we booted at. */
minmult = 30;
maxmult = longhaul_get_cpu_mult(); maxmult = longhaul_get_cpu_mult();
minfsb = maxfsb = current_fsb;
break; break;
case 2 ... 3: case 2 ... 3:
...@@ -531,7 +533,7 @@ static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy ...@@ -531,7 +533,7 @@ static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy
} }
static void longhaul_verify(struct cpufreq_policy *policy) static int longhaul_verify(struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
...@@ -540,7 +542,7 @@ static void longhaul_verify(struct cpufreq_policy *policy) ...@@ -540,7 +542,7 @@ static void longhaul_verify(struct cpufreq_policy *policy)
unsigned int newmax = -1; unsigned int newmax = -1;
if (!policy || !longhaul_driver) if (!policy || !longhaul_driver)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
cpufreq_verify_within_limits(policy, lowest_speed, highest_speed); cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
...@@ -552,7 +554,7 @@ static void longhaul_verify(struct cpufreq_policy *policy) ...@@ -552,7 +554,7 @@ static void longhaul_verify(struct cpufreq_policy *policy)
number_states = longhaul_statecount_fsb(policy, current_fsb); number_states = longhaul_statecount_fsb(policy, current_fsb);
if (number_states) if (number_states)
return; return 0;
/* get frequency closest above current policy->max */ /* get frequency closest above current policy->max */
if (can_scale_fsb==1) { if (can_scale_fsb==1) {
...@@ -579,10 +581,12 @@ static void longhaul_verify(struct cpufreq_policy *policy) ...@@ -579,10 +581,12 @@ static void longhaul_verify(struct cpufreq_policy *policy)
} }
policy->max = newmax; policy->max = newmax;
return 0;
} }
static void longhaul_setpolicy (struct cpufreq_policy *policy) static int longhaul_setpolicy (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
...@@ -592,7 +596,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy) ...@@ -592,7 +596,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
unsigned int best_freq = -1; unsigned int best_freq = -1;
if (!longhaul_driver) if (!longhaul_driver)
return; return -EINVAL;
if (policy->policy==CPUFREQ_POLICY_PERFORMANCE) if (policy->policy==CPUFREQ_POLICY_PERFORMANCE)
fsb_search_table = perf_fsb_table; fsb_search_table = perf_fsb_table;
...@@ -613,7 +617,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy) ...@@ -613,7 +617,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
} }
if (!number_states) if (!number_states)
return; return -EINVAL;
else if (number_states == 1) { else if (number_states == 1) {
for(i=0; i<numscales; i++) { for(i=0; i<numscales; i++) {
if ((clock_ratio[i] != -1) && if ((clock_ratio[i] != -1) &&
...@@ -692,11 +696,11 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy) ...@@ -692,11 +696,11 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
} }
break; break;
default: default:
return; return -EINVAL;
} }
longhaul_setstate(new_clock_ratio, new_fsb); longhaul_setstate(new_clock_ratio, new_fsb);
return; return 0;
} }
...@@ -775,7 +779,7 @@ static int __init longhaul_init (void) ...@@ -775,7 +779,7 @@ static int __init longhaul_init (void)
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = (unsigned int) lowest_speed; driver->cpu_min_freq[0] = (unsigned int) lowest_speed;
driver->cpu_cur_freq[0] = currentspeed; driver->cpu_cur_freq[0] = currentspeed;
#endif #endif
...@@ -788,15 +792,15 @@ static int __init longhaul_init (void) ...@@ -788,15 +792,15 @@ static int __init longhaul_init (void)
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].max_cpu_freq = (unsigned int) highest_speed; driver->policy[0].max_cpu_freq = (unsigned int) highest_speed;
ret = cpufreq_register(driver); longhaul_driver = driver;
ret = cpufreq_register(driver);
if (ret) { if (ret) {
longhaul_driver = NULL;
kfree(driver); kfree(driver);
return ret;
} }
longhaul_driver = driver; return ret;
return 0;
} }
......
/* /*
* $Id: longrun.c,v 1.12 2002/09/29 23:43:10 db Exp $ * $Id: longrun.c,v 1.14 2002/10/31 21:17:40 db Exp $
* *
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
* *
...@@ -67,13 +67,13 @@ static void longrun_get_policy(struct cpufreq_policy *policy) ...@@ -67,13 +67,13 @@ static void longrun_get_policy(struct cpufreq_policy *policy)
* Sets a new CPUFreq policy on LongRun-capable processors. This function * Sets a new CPUFreq policy on LongRun-capable processors. This function
* has to be called with cpufreq_driver locked. * has to be called with cpufreq_driver locked.
*/ */
static void longrun_set_policy(struct cpufreq_policy *policy) static int longrun_set_policy(struct cpufreq_policy *policy)
{ {
u32 msr_lo, msr_hi; u32 msr_lo, msr_hi;
u32 pctg_lo, pctg_hi; u32 pctg_lo, pctg_hi;
if (!longrun_driver || !policy) if (!longrun_driver || !policy)
return; return -EINVAL;
pctg_lo = (policy->min - longrun_low_freq) / pctg_lo = (policy->min - longrun_low_freq) /
((longrun_high_freq - longrun_low_freq) / 100); ((longrun_high_freq - longrun_low_freq) / 100);
...@@ -105,7 +105,7 @@ static void longrun_set_policy(struct cpufreq_policy *policy) ...@@ -105,7 +105,7 @@ static void longrun_set_policy(struct cpufreq_policy *policy)
msr_hi |= pctg_hi; msr_hi |= pctg_hi;
wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
return; return 0;
} }
...@@ -115,16 +115,16 @@ static void longrun_set_policy(struct cpufreq_policy *policy) ...@@ -115,16 +115,16 @@ static void longrun_set_policy(struct cpufreq_policy *policy)
* Validates a new CPUFreq policy. This function has to be called with * Validates a new CPUFreq policy. This function has to be called with
* cpufreq_driver locked. * cpufreq_driver locked.
*/ */
static void longrun_verify_policy(struct cpufreq_policy *policy) static int longrun_verify_policy(struct cpufreq_policy *policy)
{ {
if (!policy || !longrun_driver) if (!policy || !longrun_driver)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
cpufreq_verify_within_limits(policy, 0, cpufreq_verify_within_limits(policy, 0,
longrun_driver->policy[0].max_cpu_freq); longrun_driver->policy[0].max_cpu_freq);
return; return 0;
} }
...@@ -252,20 +252,22 @@ static int __init longrun_init(void) ...@@ -252,20 +252,22 @@ static int __init longrun_init(void)
longrun_get_policy(&driver->policy[0]); longrun_get_policy(&driver->policy[0]);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = longrun_low_freq; driver->cpu_min_freq[0] = longrun_low_freq;
driver->cpu_cur_freq[0] = longrun_high_freq; /* dummy value */ driver->cpu_cur_freq[0] = longrun_high_freq; /* dummy value */
#endif #endif
driver->verify = &longrun_verify_policy; driver->verify = &longrun_verify_policy;
driver->setpolicy = &longrun_set_policy; driver->setpolicy = &longrun_set_policy;
longrun_driver = driver;
result = cpufreq_register(driver); result = cpufreq_register(driver);
if (result) { if (result) {
longrun_driver = NULL;
kfree(driver); kfree(driver);
return result;
} }
longrun_driver = driver;
return 0; return result;
} }
......
...@@ -78,7 +78,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) ...@@ -78,7 +78,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
} }
#endif #endif
set_cpus_allowed(current, affected_cpu_map); set_cpus_allowed(current, affected_cpu_map);
BUG_ON(!(smp_processor_id() & affected_cpu_map)); BUG_ON(!(affected_cpu_map & (1 << smp_processor_id())));
/* get current state */ /* get current state */
rdmsr(MSR_IA32_THERM_CONTROL, l, h); rdmsr(MSR_IA32_THERM_CONTROL, l, h);
...@@ -136,14 +136,14 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) ...@@ -136,14 +136,14 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
} }
static void cpufreq_p4_setpolicy(struct cpufreq_policy *policy) static int cpufreq_p4_setpolicy(struct cpufreq_policy *policy)
{ {
unsigned int i; unsigned int i;
unsigned int newstate = 0; unsigned int newstate = 0;
unsigned int number_states = 0; unsigned int number_states = 0;
if (!cpufreq_p4_driver || !stock_freq || !policy) if (!cpufreq_p4_driver || !stock_freq || !policy)
return; return -EINVAL;
if (policy->policy == CPUFREQ_POLICY_POWERSAVE) if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
{ {
...@@ -183,16 +183,17 @@ static void cpufreq_p4_setpolicy(struct cpufreq_policy *policy) ...@@ -183,16 +183,17 @@ static void cpufreq_p4_setpolicy(struct cpufreq_policy *policy)
min_state = newstate - (number_states - 1); min_state = newstate - (number_states - 1);
} }
} */ } */
return 0;
} }
static void cpufreq_p4_verify(struct cpufreq_policy *policy) static int cpufreq_p4_verify(struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
if (!cpufreq_p4_driver || !stock_freq || !policy) if (!cpufreq_p4_driver || !stock_freq || !policy)
return; return -EINVAL;
if (!cpu_online(policy->cpu)) if (!cpu_online(policy->cpu))
policy->cpu = CPUFREQ_ALL_CPUS; policy->cpu = CPUFREQ_ALL_CPUS;
...@@ -205,10 +206,10 @@ static void cpufreq_p4_verify(struct cpufreq_policy *policy) ...@@ -205,10 +206,10 @@ static void cpufreq_p4_verify(struct cpufreq_policy *policy)
number_states++; number_states++;
if (number_states) if (number_states)
return; return 0;
policy->max = (stock_freq / 8) * (((unsigned int) ((policy->max * 8) / stock_freq)) + 1); policy->max = (stock_freq / 8) * (((unsigned int) ((policy->max * 8) / stock_freq)) + 1);
return; return 0;
} }
...@@ -255,9 +256,10 @@ int __init cpufreq_p4_init(void) ...@@ -255,9 +256,10 @@ int __init cpufreq_p4_init(void)
stock_freq = cpu_khz; stock_freq = cpu_khz;
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = stock_freq / 8; for (i=0;i<NR_CPUS;i++) {
for (i=0;i<NR_CPUS;i++) driver->cpu_min_freq[i] = stock_freq / 8;
driver->cpu_cur_freq[i] = stock_freq; driver->cpu_cur_freq[i] = stock_freq;
}
#endif #endif
driver->verify = &cpufreq_p4_verify; driver->verify = &cpufreq_p4_verify;
...@@ -274,15 +276,15 @@ int __init cpufreq_p4_init(void) ...@@ -274,15 +276,15 @@ int __init cpufreq_p4_init(void)
driver->policy[i].cpu = i; driver->policy[i].cpu = i;
} }
cpufreq_p4_driver = driver;
ret = cpufreq_register(driver); ret = cpufreq_register(driver);
if (ret) { if (ret) {
cpufreq_p4_driver = NULL;
kfree(driver); kfree(driver);
return ret;
} }
cpufreq_p4_driver = driver; return ret;
return 0;
} }
......
/* /*
* $Id: powernow-k6.c,v 1.33 2002/09/29 23:43:11 db Exp $ * $Id: powernow-k6.c,v 1.36 2002/10/31 21:17:40 db Exp $
* This file was part of Powertweak Linux (http://powertweak.sf.net) * This file was part of Powertweak Linux (http://powertweak.sf.net)
* and is shared with the Linux Kernel module. * and is shared with the Linux Kernel module.
* *
...@@ -113,13 +113,13 @@ static void powernow_k6_set_state (unsigned int best_i) ...@@ -113,13 +113,13 @@ static void powernow_k6_set_state (unsigned int best_i)
* Policy must be within lowest and highest possible CPU Frequency, * Policy must be within lowest and highest possible CPU Frequency,
* and at least one possible state must be within min and max. * and at least one possible state must be within min and max.
*/ */
static void powernow_k6_verify(struct cpufreq_policy *policy) static int powernow_k6_verify(struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i, j; unsigned int i, j;
if (!policy || !busfreq) if (!policy || !busfreq)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
cpufreq_verify_within_limits(policy, (20 * busfreq), cpufreq_verify_within_limits(policy, (20 * busfreq),
...@@ -131,7 +131,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy) ...@@ -131,7 +131,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
number_states++; number_states++;
if (number_states) if (number_states)
return; return 0;
/* no state is available within range -- find next larger state */ /* no state is available within range -- find next larger state */
...@@ -144,7 +144,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy) ...@@ -144,7 +144,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
policy->max = clock_ratio[j] * busfreq; policy->max = clock_ratio[j] * busfreq;
return; return 0;
} }
...@@ -154,13 +154,13 @@ static void powernow_k6_verify(struct cpufreq_policy *policy) ...@@ -154,13 +154,13 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
* *
* sets a new CPUFreq policy * sets a new CPUFreq policy
*/ */
static void powernow_k6_setpolicy (struct cpufreq_policy *policy) static int powernow_k6_setpolicy (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i, j=4; unsigned int i, j=4;
if (!powernow_driver) if (!powernow_driver)
return; return -EINVAL;
for (i=0; i<8; i++) for (i=0; i<8; i++)
if ((policy->min <= (busfreq * clock_ratio[i])) && if ((policy->min <= (busfreq * clock_ratio[i])) &&
...@@ -174,7 +174,7 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy) ...@@ -174,7 +174,7 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy)
/* if only one state is within the limit borders, it /* if only one state is within the limit borders, it
is easily detected and set */ is easily detected and set */
powernow_k6_set_state(j); powernow_k6_set_state(j);
return; return 0;
} }
/* more than one state within limit */ /* more than one state within limit */
...@@ -196,14 +196,14 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy) ...@@ -196,14 +196,14 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy)
j = i; j = i;
break; break;
default: default:
return; return -EINVAL;
} }
if (clock_ratio[i] > max_multiplier) if (clock_ratio[i] > max_multiplier)
BUG(); return -EINVAL;
powernow_k6_set_state(j); powernow_k6_set_state(j);
return; return 0;
} }
...@@ -242,7 +242,7 @@ static int __init powernow_k6_init(void) ...@@ -242,7 +242,7 @@ static int __init powernow_k6_init(void)
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = busfreq * 20; driver->cpu_min_freq[0] = busfreq * 20;
driver->cpu_cur_freq[0] = busfreq * max_multiplier; driver->cpu_cur_freq[0] = busfreq * max_multiplier;
#endif #endif
...@@ -255,16 +255,16 @@ static int __init powernow_k6_init(void) ...@@ -255,16 +255,16 @@ static int __init powernow_k6_init(void)
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].max_cpu_freq = busfreq * max_multiplier; driver->policy[0].max_cpu_freq = busfreq * max_multiplier;
powernow_driver = driver;
result = cpufreq_register(driver); result = cpufreq_register(driver);
if (result) { if (result) {
release_region (POWERNOW_IOPORT, 16); release_region (POWERNOW_IOPORT, 16);
powernow_driver = NULL;
kfree(driver); kfree(driver);
return result;
} }
powernow_driver = driver;
return 0; return result;
} }
......
/* /*
* $Id: speedstep.c,v 1.57 2002/11/05 12:01:12 db Exp $ * $Id: speedstep.c,v 1.58 2002/11/11 15:35:46 db Exp $
* *
* (C) 2001 Dave Jones, Arjan van de ven. * (C) 2001 Dave Jones, Arjan van de ven.
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
...@@ -567,10 +567,10 @@ static int speedstep_detect_speeds (void) ...@@ -567,10 +567,10 @@ static int speedstep_detect_speeds (void)
* *
* Sets a new CPUFreq policy. * Sets a new CPUFreq policy.
*/ */
static void speedstep_setpolicy (struct cpufreq_policy *policy) static int speedstep_setpolicy (struct cpufreq_policy *policy)
{ {
if (!speedstep_driver || !policy) if (!speedstep_driver || !policy)
return; return -EINVAL;
if (policy->min > speedstep_low_freq) if (policy->min > speedstep_low_freq)
speedstep_set_state(SPEEDSTEP_HIGH, 1); speedstep_set_state(SPEEDSTEP_HIGH, 1);
...@@ -585,6 +585,7 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy) ...@@ -585,6 +585,7 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy)
speedstep_set_state(SPEEDSTEP_HIGH, 1); speedstep_set_state(SPEEDSTEP_HIGH, 1);
} }
} }
return 0;
} }
...@@ -595,11 +596,11 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy) ...@@ -595,11 +596,11 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy)
* Limit must be within speedstep_low_freq and speedstep_high_freq, with * Limit must be within speedstep_low_freq and speedstep_high_freq, with
* at least one border included. * at least one border included.
*/ */
static void speedstep_verify (struct cpufreq_policy *policy) static int speedstep_verify (struct cpufreq_policy *policy)
{ {
if (!policy || !speedstep_driver || if (!policy || !speedstep_driver ||
!speedstep_low_freq || !speedstep_high_freq) !speedstep_low_freq || !speedstep_high_freq)
return; return -EINVAL;
policy->cpu = 0; /* UP only */ policy->cpu = 0; /* UP only */
...@@ -609,7 +610,7 @@ static void speedstep_verify (struct cpufreq_policy *policy) ...@@ -609,7 +610,7 @@ static void speedstep_verify (struct cpufreq_policy *policy)
(policy->max < speedstep_high_freq)) (policy->max < speedstep_high_freq))
policy->max = speedstep_high_freq; policy->max = speedstep_high_freq;
return; return 0;
} }
...@@ -654,12 +655,11 @@ static int __init speedstep_init(void) ...@@ -654,12 +655,11 @@ static int __init speedstep_init(void)
speedstep_processor = speedstep_detect_processor(); speedstep_processor = speedstep_detect_processor();
if ((!speedstep_chipset) || (!speedstep_processor)) { if ((!speedstep_chipset) || (!speedstep_processor)) {
printk(KERN_INFO "a 0x%x b 0x%x\n", speedstep_processor, speedstep_chipset);
printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this %s not (yet) available.\n", speedstep_chipset ? "processor" : "chipset"); printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this %s not (yet) available.\n", speedstep_chipset ? "processor" : "chipset");
return -ENODEV; return -ENODEV;
} }
dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.57 $\n"); dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.58 $\n");
dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n", dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n",
speedstep_chipset, speedstep_processor); speedstep_chipset, speedstep_processor);
...@@ -693,7 +693,7 @@ static int __init speedstep_init(void) ...@@ -693,7 +693,7 @@ static int __init speedstep_init(void)
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = speedstep_low_freq; driver->cpu_min_freq[0] = speedstep_low_freq;
driver->cpu_cur_freq[0] = speed; driver->cpu_cur_freq[0] = speed;
#endif #endif
...@@ -707,14 +707,15 @@ static int __init speedstep_init(void) ...@@ -707,14 +707,15 @@ static int __init speedstep_init(void)
driver->policy[0].policy = (speed == speedstep_low_freq) ? driver->policy[0].policy = (speed == speedstep_low_freq) ?
CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE; CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
speedstep_driver = driver;
result = cpufreq_register(driver); result = cpufreq_register(driver);
if (result) { if (result) {
speedstep_driver = NULL;
kfree(driver); kfree(driver);
return result;
} }
speedstep_driver = driver;
return 0; return result;
} }
......
...@@ -1475,11 +1475,8 @@ linux_syscall_trace: ...@@ -1475,11 +1475,8 @@ linux_syscall_trace:
.globl C_LABEL(ret_from_fork) .globl C_LABEL(ret_from_fork)
C_LABEL(ret_from_fork): C_LABEL(ret_from_fork):
#if CONFIG_SMP || CONFIG_PREEMPT
/* XXX Wrong location: call schedule_tail in every ret_sys_call. */
call schedule_tail call schedule_tail
mov %g3, %o0 mov %g3, %o0
#endif
b C_LABEL(ret_sys_call) b C_LABEL(ret_sys_call)
ld [%sp + REGWIN_SZ + PT_I0], %o0 ld [%sp + REGWIN_SZ + PT_I0], %o0
......
...@@ -457,16 +457,20 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, ...@@ -457,16 +457,20 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
struct pt_regs *regs, struct pt_regs *regs,
unsigned long stack_size) unsigned long stack_size)
{ {
unsigned long tid_ptr = 0; unsigned long parent_tid_ptr = 0;
unsigned long child_tid_ptr = 0;
struct task_struct *p; struct task_struct *p;
clone_flags &= ~CLONE_IDLETASK; clone_flags &= ~CLONE_IDLETASK;
if (clone_flags & (CLONE_SETTID | CLONE_CLEARTID)) if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
tid_ptr = regs->u_regs[UREG_G2]; parent_tid_ptr = regs->u_regs[UREG_G2];
child_tid_ptr = regs->u_regs[UREG_G3];
}
p = do_fork(clone_flags, stack_start, p = do_fork(clone_flags, stack_start,
regs, stack_size, (int *) tid_ptr); regs, stack_size,
(int *) parent_tid_ptr,
(int *) child_tid_ptr);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
...@@ -507,7 +511,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -507,7 +511,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
#endif #endif
} }
p->user_tid = NULL; p->set_child_tid = p->clear_child_tid = NULL;
/* Calculate offset to stack_frame & pt_regs */ /* Calculate offset to stack_frame & pt_regs */
stack_offset = THREAD_SIZE - TRACEREG_SZ; stack_offset = THREAD_SIZE - TRACEREG_SZ;
...@@ -582,16 +586,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -582,16 +586,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
/* Set the return value for the parent. */ /* Set the return value for the parent. */
regs->u_regs[UREG_I1] = 0; regs->u_regs[UREG_I1] = 0;
if (!(clone_flags & (CLONE_SETTID | CLONE_CLEARTID)))
return 0;
if (clone_flags & CLONE_SETTID)
if (put_user(p->pid, (int *)childregs->u_regs[UREG_G2]))
return -EFAULT;
if (clone_flags & CLONE_CLEARTID)
p->user_tid = (int *) childregs->u_regs[UREG_G2];
return 0; return 0;
} }
......
...@@ -1619,10 +1619,8 @@ ret_from_syscall: ...@@ -1619,10 +1619,8 @@ ret_from_syscall:
*/ */
andn %o7, _TIF_NEWCHILD, %l0 andn %o7, _TIF_NEWCHILD, %l0
stx %l0, [%g6 + TI_FLAGS] stx %l0, [%g6 + TI_FLAGS]
#if CONFIG_SMP || CONFIG_PREEMPT
call schedule_tail call schedule_tail
mov %g5, %o0 mov %g5, %o0
#endif
andcc %l0, _TIF_PERFCTR, %g0 andcc %l0, _TIF_PERFCTR, %g0
be,pt %icc, 1f be,pt %icc, 1f
nop nop
......
...@@ -568,18 +568,24 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, ...@@ -568,18 +568,24 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
unsigned long stack_size) unsigned long stack_size)
{ {
struct task_struct *p; struct task_struct *p;
unsigned long tid_ptr = 0; unsigned long parent_tid_ptr = 0;
unsigned long child_tid_ptr = 0;
clone_flags &= ~CLONE_IDLETASK; clone_flags &= ~CLONE_IDLETASK;
if (clone_flags & (CLONE_SETTID | CLONE_CLEARTID)) { if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
tid_ptr = regs->u_regs[UREG_G2]; parent_tid_ptr = regs->u_regs[UREG_G2];
if (test_thread_flag(TIF_32BIT)) child_tid_ptr = regs->u_regs[UREG_G3];
tid_ptr &= 0xffffffff; if (test_thread_flag(TIF_32BIT)) {
parent_tid_ptr &= 0xffffffff;
child_tid_ptr &= 0xffffffff;
}
} }
p = do_fork(clone_flags, stack_start, p = do_fork(clone_flags, stack_start,
regs, stack_size, (int *) tid_ptr); regs, stack_size,
(int *) parent_tid_ptr,
(int *) child_tid_ptr);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
...@@ -601,7 +607,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -601,7 +607,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
p->thread.smp_lock_pc = 0; p->thread.smp_lock_pc = 0;
#endif #endif
p->user_tid = NULL; p->set_child_tid = p->clear_child_tid = NULL;
/* Calculate offset to stack_frame & pt_regs */ /* Calculate offset to stack_frame & pt_regs */
child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+REGWIN_SZ)); child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+REGWIN_SZ));
......
...@@ -1613,7 +1613,7 @@ acpi_processor_get_limit_info ( ...@@ -1613,7 +1613,7 @@ acpi_processor_get_limit_info (
cpufreq interface cpufreq interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCESSOR_PERF #ifdef CONFIG_ACPI_PROCESSOR_PERF
static void static int
acpi_cpufreq_setpolicy ( acpi_cpufreq_setpolicy (
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
{ {
...@@ -1626,7 +1626,7 @@ acpi_cpufreq_setpolicy ( ...@@ -1626,7 +1626,7 @@ acpi_cpufreq_setpolicy (
ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy"); ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
if (!policy) if (!policy)
return_VOID; return_VALUE(-EINVAL);
/* get a present, initialized CPU */ /* get a present, initialized CPU */
if (policy->cpu == CPUFREQ_ALL_CPUS) if (policy->cpu == CPUFREQ_ALL_CPUS)
...@@ -1644,7 +1644,7 @@ acpi_cpufreq_setpolicy ( ...@@ -1644,7 +1644,7 @@ acpi_cpufreq_setpolicy (
cpu = policy->cpu; cpu = policy->cpu;
pr = processors[cpu]; pr = processors[cpu];
if (!pr) if (!pr)
return_VOID; return_VALUE(-EINVAL);
} }
/* select appropriate P-State */ /* select appropriate P-State */
...@@ -1686,11 +1686,11 @@ acpi_cpufreq_setpolicy ( ...@@ -1686,11 +1686,11 @@ acpi_cpufreq_setpolicy (
result = acpi_processor_set_performance (pr, next_state); result = acpi_processor_set_performance (pr, next_state);
} }
return_VOID; return_VALUE(0);
} }
static void static int
acpi_cpufreq_verify ( acpi_cpufreq_verify (
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
{ {
...@@ -1703,7 +1703,7 @@ acpi_cpufreq_verify ( ...@@ -1703,7 +1703,7 @@ acpi_cpufreq_verify (
ACPI_FUNCTION_TRACE("acpi_cpufreq_verify"); ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
if (!policy) if (!policy)
return_VOID; return_VALUE(-EINVAL);
/* get a present, initialized CPU */ /* get a present, initialized CPU */
if (policy->cpu == CPUFREQ_ALL_CPUS) if (policy->cpu == CPUFREQ_ALL_CPUS)
...@@ -1721,7 +1721,7 @@ acpi_cpufreq_verify ( ...@@ -1721,7 +1721,7 @@ acpi_cpufreq_verify (
cpu = policy->cpu; cpu = policy->cpu;
pr = processors[cpu]; pr = processors[cpu];
if (!pr) if (!pr)
return_VOID; return_VALUE(-EINVAL);
} }
/* first check if min and max are within valid limits */ /* first check if min and max are within valid limits */
...@@ -1741,13 +1741,12 @@ acpi_cpufreq_verify ( ...@@ -1741,13 +1741,12 @@ acpi_cpufreq_verify (
next_larger_state = i; next_larger_state = i;
} }
if (number_states) if (!number_states) {
return_VOID; /* round up now */
policy->max = pr->performance.states[next_larger_state].core_frequency * 1000;
/* round up now */ }
policy->max = pr->performance.states[next_larger_state].core_frequency * 1000;
return_VOID; return_VALUE(0);
} }
static int static int
...@@ -1807,9 +1806,10 @@ acpi_cpufreq_init ( ...@@ -1807,9 +1806,10 @@ acpi_cpufreq_init (
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000; for (i=0;i<NR_CPUS;i++) {
for (i=0;i<NR_CPUS;i++)
driver->cpu_cur_freq[0] = pr->performance.states[current_state].core_frequency * 1000; driver->cpu_cur_freq[0] = pr->performance.states[current_state].core_frequency * 1000;
driver->cpu_min_freq[0] = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000;
}
#endif #endif
driver->verify = &acpi_cpufreq_verify; driver->verify = &acpi_cpufreq_verify;
......
...@@ -636,289 +636,7 @@ comment "from the tpqic02-support package. It is available at" ...@@ -636,289 +636,7 @@ comment "from the tpqic02-support package. It is available at"
comment "metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/" comment "metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/"
depends on QIC02_TAPE && QIC02_DYNCONF depends on QIC02_TAPE && QIC02_DYNCONF
source "drivers/char/watchdog/Kconfig"
menu "Watchdog Cards"
config WATCHDOG
bool "Watchdog Timer Support"
---help---
If you say Y here (and to one of the following options) and create a
character special file /dev/watchdog with major number 10 and minor
number 130 using mknod ("man mknod"), you will get a watchdog, i.e.:
subsequently opening the file and then failing to write to it for
longer than 1 minute will result in rebooting the machine. This
could be useful for a networked machine that needs to come back
online as fast as possible after a lock-up. There's both a watchdog
implementation entirely in software (which can sometimes fail to
reboot the machine) and a driver for hardware watchdog boards, which
are more robust and can also keep track of the temperature inside
your computer. For details, read <file:Documentation/watchdog.txt>
in the kernel source.
The watchdog is usually used together with the watchdog daemon
which is available from
<ftp://ibiblio.org/pub/Linux/system/daemons/watchdog/>. This daemon can
also monitor NFS connections and can reboot the machine when the process
table is full.
If unsure, say N.
config WATCHDOG_NOWAYOUT
bool "Disable watchdog shutdown on close"
depends on WATCHDOG
help
The default watchdog behaviour (which you get if you say N here) is
to stop the timer if the process managing it closes the file
/dev/watchdog. It's always remotely possible that this process might
get killed. If you say Y here, the watchdog cannot be stopped once
it has been started.
config SOFT_WATCHDOG
tristate "Software watchdog"
depends on WATCHDOG
help
A software monitoring watchdog. This will fail to reboot your system
from some situations that the hardware watchdog will recover
from. Equally it's a lot cheaper to install.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. The module will be called
softdog.o.
config WDT
tristate "WDT Watchdog timer"
depends on WATCHDOG
---help---
If you have a WDT500P or WDT501P watchdog board, say Y here,
otherwise N. It is not possible to probe for this board, which means
that you have to inform the kernel about the IO port and IRQ using
the "wdt=" kernel option (try "man bootparam" or see the
documentation of your boot loader (lilo or loadlin) about how to
pass options to the kernel at boot time).
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called wdt.o.
config WDTPCI
tristate "WDT PCI Watchdog timer"
depends on WATCHDOG
---help---
If you have a PCI WDT500/501 watchdog board, say Y here, otherwise
N. It is not possible to probe for this board, which means that you
have to inform the kernel about the IO port and IRQ using the "wdt="
kernel option (try "man bootparam" or see the documentation of your
boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time).
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called wdt_pci.o.
config WDT_501
bool "WDT501 features"
depends on WDT
help
Saying Y here and creating a character special file /dev/temperature
with major number 10 and minor number 131 ("man mknod") will give
you a thermometer inside your computer: reading from
/dev/temperature yields one byte, the temperature in degrees
Fahrenheit. This works only if you have a WDT501P watchdog board
installed.
config WDT_501_FAN
bool "Fan Tachometer"
depends on WDT_501
help
Enable the Fan Tachometer on the WDT501. Only do this if you have a
fan tachometer actually set up.
config PCWATCHDOG
tristate "Berkshire Products PC Watchdog"
depends on WATCHDOG
---help---
This is the driver for the Berkshire Products PC Watchdog card.
This card simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
time. This driver is like the WDT501 driver but for different
hardware. Please read <file:Documentation/pcwd-watchdog.txt>. The PC
watchdog cards can be ordered from <http://www.berkprod.com/>.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called pcwd.o. If you want to compile it as a module,
say M here and read <file:Documentation/modules.txt>.
Most people will say N.
config ACQUIRE_WDT
tristate "Acquire SBC Watchdog Timer"
depends on WATCHDOG
---help---
This is the driver for the hardware watchdog on the PSC-6x86 Single
Board Computer produced by Acquire Inc (and others). This watchdog
simply watches your kernel to make sure it doesn't freeze, and if
it does, it reboots your computer after a certain amount of time.
This driver is like the WDT501 driver but for different hardware.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called pscwdt.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. Most
people will say N.
config ADVANTECH_WDT
tristate "Advantech SBC Watchdog Timer"
depends on WATCHDOG
help
If you are configuring a Linux kernel for the Advantech single-board
computer, say `Y' here to support its built-in watchdog timer
feature. See the help for CONFIG_WATCHDOG for discussion.
config 21285_WATCHDOG
tristate "DC21285 watchdog"
depends on WATCHDOG && FOOTBRIDGE
help
The Intel Footbridge chip contains a builtin watchdog circuit. Say Y
here if you wish to use this. Alternatively say M to compile the
driver as a module, which will be called wdt285.o.
This driver does not work on all machines. In particular, early CATS
boards have hardware problems that will cause the machine to simply
lock up if the watchdog fires.
"If in doubt, leave it out" - say N.
config 977_WATCHDOG
tristate "NetWinder WB83C977 watchdog"
depends on WATCHDOG && FOOTBRIDGE && ARCH_NETWINDER
help
Say Y here to include support for the WB977 watchdog included in
NetWinder machines. Alternatively say M to compile the driver as
a module, which will be called wdt977.o.
Not sure? It's safe to say N.
config EUROTECH_WDT
tristate "Eurotech CPU-1220/1410 Watchdog Timer"
depends on WATCHDOG
help
Enable support for the watchdog timer on the Eurotech CPU-1220 and
CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product
information are at <http://www.eurotech.it/>.
config IB700_WDT
tristate "IB700 SBC Watchdog Timer"
depends on WATCHDOG
---help---
This is the driver for the hardware watchdog on the IB700 Single
Board Computer produced by TMC Technology (www.tmc-uk.com). This watchdog
simply watches your kernel to make sure it doesn't freeze, and if
it does, it reboots your computer after a certain amount of time.
This driver is like the WDT501 driver but for slightly different hardware.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called ib700wdt.o. If you want to compile it as a
module, say M here and read Documentation/modules.txt. Most people
will say N.
config I810_TCO
tristate "Intel i810 TCO timer / Watchdog"
depends on WATCHDOG
---help---
Hardware driver for the TCO timer built into the Intel i810 and i815
chipset family. The TCO (Total Cost of Ownership) timer is a
watchdog timer that will reboot the machine after its second
expiration. The expiration time can be configured by commandline
argument "i810_margin=<n>" where <n> is the counter initial value.
It is decremented every 0.6 secs, the default is 50 which gives a
timeout of 30 seconds and one minute until reset.
On some motherboards the driver may fail to reset the chipset's
NO_REBOOT flag which prevents the watchdog from rebooting the
machine. If this is the case you will get a kernel message like
"i810tco init: failed to reset NO_REBOOT flag".
If you want to compile this as a module, say M and read
<file:Documentation/modules.txt>. The module will be called
i810-tco.o.
config MIXCOMWD
tristate "Mixcom Watchdog"
depends on WATCHDOG
---help---
This is a driver for the Mixcom hardware watchdog cards. This
watchdog simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
time.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called mixcomwd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. Most
people will say N.
config SCx200_WDT
tristate "NatSemi SCx200 Watchdog"
depends on WATCHDOG
help
Enable the built-in watchdog timer support on the National
Semiconductor SCx200 processors.
If compiled as a module, it will be called scx200_watchdog.o.
config 60XX_WDT
tristate "SBC-60XX Watchdog Timer"
depends on WATCHDOG
help
This driver can be used with the watchdog timer found on some
single board computers, namely the 6010 PII based computer.
It may well work with other cards. It reads port 0x443 to enable
and re-set the watchdog timer, and reads port 0x45 to disable
the watchdog. If you have a card that behave in similar ways,
you can probably make this driver work with your card as well.
You can compile this driver directly into the kernel, or use
it as a module. The module will be called sbc60xxwdt.o.
config W83877F_WDT
tristate "W83877F (EMACS) Watchdog Timer"
depends on WATCHDOG
---help---
This is the driver for the hardware watchdog on the W83877F chipset
as used in EMACS PC-104 motherboards (and likely others). This
watchdog simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
time.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called mixcomwd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. Most
people will say N.
config MACHZ_WDT
tristate "ZF MachZ Watchdog"
depends on WATCHDOG
---help---
If you are using a ZF Micro MachZ processor, say Y here, otherwise
N. This is the driver for the watchdog timer builtin on that
processor using ZF-Logic interface. This watchdog simply watches
your kernel to make sure it doesn't freeze, and if it does, it
reboots your computer after a certain amount of time.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called machzwd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
endmenu
config DS1620 config DS1620
tristate "NetWinder thermometer support" tristate "NetWinder thermometer support"
......
...@@ -77,32 +77,13 @@ obj-$(CONFIG_NWBUTTON) += nwbutton.o ...@@ -77,32 +77,13 @@ obj-$(CONFIG_NWBUTTON) += nwbutton.o
obj-$(CONFIG_NWFLASH) += nwflash.o obj-$(CONFIG_NWFLASH) += nwflash.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
# Only one watchdog can succeed. We probe the hardware watchdog obj-$(CONFIG_WATCHDOGS) += watchdog/
# drivers first, then the softdog driver. This means if your hardware
# watchdog dies or is 'borrowed' for some reason the software watchdog
# still gives you some cover.
obj-$(CONFIG_PCWATCHDOG) += pcwd.o
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
obj-$(CONFIG_IB700_WDT) += ib700wdt.o
obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_WDT) += wdt.o
obj-$(CONFIG_WDTPCI) += wdt_pci.o
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
obj-$(CONFIG_I810_TCO) += i810-tco.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o
obj-$(CONFIG_SH_WDT) += shwdt.o
obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
obj-$(CONFIG_MWAVE) += mwave/ obj-$(CONFIG_MWAVE) += mwave/
obj-$(CONFIG_AGP) += agp/ obj-$(CONFIG_AGP) += agp/
obj-$(CONFIG_DRM) += drm/ obj-$(CONFIG_DRM) += drm/
obj-$(CONFIG_PCMCIA) += pcmcia/ obj-$(CONFIG_PCMCIA) += pcmcia/
# Files generated that shall be removed upon make clean # Files generated that shall be removed upon make clean
clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
......
/* /*
* Sony Programmable I/O Control Device driver for VAIO * Sony Programmable I/O Control Device driver for VAIO
* *
* Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcve * Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
*
* Copyright (C) 2001-2002 Alcve <www.alcove.com>
* *
* Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
* *
...@@ -39,6 +41,7 @@ ...@@ -39,6 +41,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/acpi.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -53,7 +56,7 @@ static int verbose; /* = 0 */ ...@@ -53,7 +56,7 @@ static int verbose; /* = 0 */
static int fnkeyinit; /* = 0 */ static int fnkeyinit; /* = 0 */
static int camera; /* = 0 */ static int camera; /* = 0 */
static int compat; /* = 0 */ static int compat; /* = 0 */
static int nojogdial; /* = 0 */ static unsigned long mask = 0xffffffff;
/* Inits the queue */ /* Inits the queue */
static inline void sonypi_initq(void) { static inline void sonypi_initq(void) {
...@@ -113,29 +116,14 @@ static inline int sonypi_emptyq(void) { ...@@ -113,29 +116,14 @@ static inline int sonypi_emptyq(void) {
return result; return result;
} }
static void sonypi_ecrset(u8 addr, u8 value) { static int ec_read16(u8 addr, u16 *value) {
u8 val_lb, val_hb;
wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3); if (ec_read(addr, &val_lb))
outb_p(0x81, SONYPI_CST_IOPORT); return -1;
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2); if (ec_read(addr + 1, &val_hb))
outb_p(addr, SONYPI_DATA_IOPORT); return -1;
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2); *value = val_lb | (val_hb << 8);
outb_p(value, SONYPI_DATA_IOPORT); return 0;
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2);
}
static u8 sonypi_ecrget(u8 addr) {
wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3);
outb_p(0x80, SONYPI_CST_IOPORT);
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2);
outb_p(addr, SONYPI_DATA_IOPORT);
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2);
return inb_p(SONYPI_DATA_IOPORT);
}
static u16 sonypi_ecrget16(u8 addr) {
return sonypi_ecrget(addr) | (sonypi_ecrget(addr + 1) << 8);
} }
/* Initializes the device - this comes from the AML code in the ACPI bios */ /* Initializes the device - this comes from the AML code in the ACPI bios */
...@@ -162,9 +150,12 @@ static void __devinit sonypi_type1_srs(void) { ...@@ -162,9 +150,12 @@ static void __devinit sonypi_type1_srs(void) {
} }
static void __devinit sonypi_type2_srs(void) { static void __devinit sonypi_type2_srs(void) {
sonypi_ecrset(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8); if (ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
sonypi_ecrset(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF); printk(KERN_WARNING "ec_write failed\n");
sonypi_ecrset(SONYPI_SIRQ, sonypi_device.bits); if (ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF))
printk(KERN_WARNING "ec_write failed\n");
if (ec_write(SONYPI_SIRQ, sonypi_device.bits))
printk(KERN_WARNING "ec_write failed\n");
udelay(10); udelay(10);
} }
...@@ -182,15 +173,18 @@ static void __devexit sonypi_type1_dis(void) { ...@@ -182,15 +173,18 @@ static void __devexit sonypi_type1_dis(void) {
} }
static void __devexit sonypi_type2_dis(void) { static void __devexit sonypi_type2_dis(void) {
sonypi_ecrset(SONYPI_SHIB, 0); if (ec_write(SONYPI_SHIB, 0))
sonypi_ecrset(SONYPI_SLOB, 0); printk(KERN_WARNING "ec_write failed\n");
sonypi_ecrset(SONYPI_SIRQ, 0); if (ec_write(SONYPI_SLOB, 0))
printk(KERN_WARNING "ec_write failed\n");
if (ec_write(SONYPI_SIRQ, 0))
printk(KERN_WARNING "ec_write failed\n");
} }
static u8 sonypi_call1(u8 dev) { static u8 sonypi_call1(u8 dev) {
u8 v1, v2; u8 v1, v2;
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2); wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
outb(dev, sonypi_device.ioport2); outb(dev, sonypi_device.ioport2);
v1 = inb_p(sonypi_device.ioport2); v1 = inb_p(sonypi_device.ioport2);
v2 = inb_p(sonypi_device.ioport1); v2 = inb_p(sonypi_device.ioport1);
...@@ -200,9 +194,9 @@ static u8 sonypi_call1(u8 dev) { ...@@ -200,9 +194,9 @@ static u8 sonypi_call1(u8 dev) {
static u8 sonypi_call2(u8 dev, u8 fn) { static u8 sonypi_call2(u8 dev, u8 fn) {
u8 v1; u8 v1;
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2); wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
outb(dev, sonypi_device.ioport2); outb(dev, sonypi_device.ioport2);
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2); wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
outb(fn, sonypi_device.ioport1); outb(fn, sonypi_device.ioport1);
v1 = inb_p(sonypi_device.ioport1); v1 = inb_p(sonypi_device.ioport1);
return v1; return v1;
...@@ -211,11 +205,11 @@ static u8 sonypi_call2(u8 dev, u8 fn) { ...@@ -211,11 +205,11 @@ static u8 sonypi_call2(u8 dev, u8 fn) {
static u8 sonypi_call3(u8 dev, u8 fn, u8 v) { static u8 sonypi_call3(u8 dev, u8 fn, u8 v) {
u8 v1; u8 v1;
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2); wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
outb(dev, sonypi_device.ioport2); outb(dev, sonypi_device.ioport2);
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2); wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
outb(fn, sonypi_device.ioport1); outb(fn, sonypi_device.ioport1);
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2); wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
outb(v, sonypi_device.ioport1); outb(v, sonypi_device.ioport1);
v1 = inb_p(sonypi_device.ioport1); v1 = inb_p(sonypi_device.ioport1);
return v1; return v1;
...@@ -237,7 +231,7 @@ static u8 sonypi_read(u8 fn) { ...@@ -237,7 +231,7 @@ static u8 sonypi_read(u8 fn) {
/* Set brightness, hue etc */ /* Set brightness, hue etc */
static void sonypi_set(u8 fn, u8 v) { static void sonypi_set(u8 fn, u8 v) {
wait_on_command(0, sonypi_call3(0x90, fn, v)); wait_on_command(0, sonypi_call3(0x90, fn, v), ITERATIONS_SHORT);
} }
/* Tests if the camera is ready */ /* Tests if the camera is ready */
...@@ -311,79 +305,30 @@ static void sonypi_setbluetoothpower(u8 state) { ...@@ -311,79 +305,30 @@ static void sonypi_setbluetoothpower(u8 state) {
/* Interrupt handler: some event is available */ /* Interrupt handler: some event is available */
void sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) { void sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) {
u8 v1, v2, event = 0; u8 v1, v2, event = 0;
int i; int i, j;
u8 sonypi_jogger_ev, sonypi_fnkey_ev;
u8 sonypi_capture_ev, sonypi_bluetooth_ev;
u8 sonypi_pkey_ev;
if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
sonypi_jogger_ev = SONYPI_TYPE2_JOGGER_EV;
sonypi_fnkey_ev = SONYPI_TYPE2_FNKEY_EV;
sonypi_capture_ev = SONYPI_TYPE2_CAPTURE_EV;
sonypi_bluetooth_ev = SONYPI_TYPE2_BLUETOOTH_EV;
sonypi_pkey_ev = nojogdial ? SONYPI_TYPE2_PKEY_EV
: SONYPI_TYPE1_PKEY_EV;
}
else {
sonypi_jogger_ev = SONYPI_TYPE1_JOGGER_EV;
sonypi_fnkey_ev = SONYPI_TYPE1_FNKEY_EV;
sonypi_capture_ev = SONYPI_TYPE1_CAPTURE_EV;
sonypi_bluetooth_ev = SONYPI_TYPE1_BLUETOOTH_EV;
sonypi_pkey_ev = SONYPI_TYPE1_PKEY_EV;
}
v1 = inb_p(sonypi_device.ioport1); v1 = inb_p(sonypi_device.ioport1);
v2 = inb_p(sonypi_device.ioport2); v2 = inb_p(sonypi_device.ioport2);
if ((v2 & sonypi_pkey_ev) == sonypi_pkey_ev) { if (verbose > 1)
for (i = 0; sonypi_pkeyev[i].event; i++) printk(KERN_INFO
if (sonypi_pkeyev[i].data == v1) { "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
event = sonypi_pkeyev[i].event;
goto found; for (i = 0; sonypi_eventtypes[i].model; i++) {
} if (sonypi_device.model != sonypi_eventtypes[i].model)
} continue;
if ((v2 & sonypi_jogger_ev) == sonypi_jogger_ev) { if ((v2 & sonypi_eventtypes[i].data) != sonypi_eventtypes[i].data)
for (i = 0; sonypi_joggerev[i].event; i++) continue;
if (sonypi_joggerev[i].data == v1) { if (! (mask & sonypi_eventtypes[i].mask))
event = sonypi_joggerev[i].event; continue;
goto found; for (j = 0; sonypi_eventtypes[i].events[j].event; j++) {
} if (v1 == sonypi_eventtypes[i].events[j].data) {
} event = sonypi_eventtypes[i].events[j].event;
if ((v2 & sonypi_capture_ev) == sonypi_capture_ev) {
for (i = 0; sonypi_captureev[i].event; i++)
if (sonypi_captureev[i].data == v1) {
event = sonypi_captureev[i].event;
goto found;
}
}
if ((v2 & sonypi_fnkey_ev) == sonypi_fnkey_ev) {
for (i = 0; sonypi_fnkeyev[i].event; i++)
if (sonypi_fnkeyev[i].data == v1) {
event = sonypi_fnkeyev[i].event;
goto found;
}
}
if ((v2 & sonypi_bluetooth_ev) == sonypi_bluetooth_ev) {
for (i = 0; sonypi_blueev[i].event; i++)
if (sonypi_blueev[i].data == v1) {
event = sonypi_blueev[i].event;
goto found;
}
}
if ((v2 & SONYPI_BACK_EV) == SONYPI_BACK_EV) {
for (i = 0; sonypi_backev[i].event; i++)
if (sonypi_backev[i].data == v1) {
event = sonypi_backev[i].event;
goto found;
}
}
if ((v2 & SONYPI_LID_EV) == SONYPI_LID_EV) {
for (i = 0; sonypi_lidev[i].event; i++)
if (sonypi_lidev[i].data == v1) {
event = sonypi_lidev[i].event;
goto found; goto found;
} }
}
} }
if (verbose) if (verbose)
printk(KERN_WARNING printk(KERN_WARNING
"sonypi: unknown event port1=0x%02x,port2=0x%02x\n",v1,v2); "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",v1,v2);
...@@ -545,72 +490,77 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, ...@@ -545,72 +490,77 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
down(&sonypi_device.lock); down(&sonypi_device.lock);
switch (cmd) { switch (cmd) {
case SONYPI_IOCGBRT: case SONYPI_IOCGBRT:
val8 = sonypi_ecrget(SONYPI_LCD_LIGHT); if (ec_read(SONYPI_LCD_LIGHT, &val8)) {
if (copy_to_user((u8 *)arg, &val8, sizeof(val8))) { ret = -EIO;
ret = -EFAULT; break;
goto out;
} }
if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
ret = -EFAULT;
break; break;
case SONYPI_IOCSBRT: case SONYPI_IOCSBRT:
if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) { if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
ret = -EFAULT; ret = -EFAULT;
goto out; break;
} }
sonypi_ecrset(SONYPI_LCD_LIGHT, val8); if (ec_write(SONYPI_LCD_LIGHT, val8))
ret = -EIO;
break; break;
case SONYPI_IOCGBAT1CAP: case SONYPI_IOCGBAT1CAP:
val16 = sonypi_ecrget16(SONYPI_BAT1_FULL); if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
if (copy_to_user((u16 *)arg, &val16, sizeof(val16))) { ret = -EIO;
ret = -EFAULT; break;
goto out;
} }
if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
ret = -EFAULT;
break; break;
case SONYPI_IOCGBAT1REM: case SONYPI_IOCGBAT1REM:
val16 = sonypi_ecrget16(SONYPI_BAT1_LEFT); if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
if (copy_to_user((u16 *)arg, &val16, sizeof(val16))) { ret = -EIO;
ret = -EFAULT; break;
goto out;
} }
if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
ret = -EFAULT;
break; break;
case SONYPI_IOCGBAT2CAP: case SONYPI_IOCGBAT2CAP:
val16 = sonypi_ecrget16(SONYPI_BAT2_FULL); if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
if (copy_to_user((u16 *)arg, &val16, sizeof(val16))) { ret = -EIO;
ret = -EFAULT; break;
goto out;
} }
if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
ret = -EFAULT;
break; break;
case SONYPI_IOCGBAT2REM: case SONYPI_IOCGBAT2REM:
val16 = sonypi_ecrget16(SONYPI_BAT2_LEFT); if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
if (copy_to_user((u16 *)arg, &val16, sizeof(val16))) { ret = -EIO;
ret = -EFAULT; break;
goto out;
} }
if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
ret = -EFAULT;
break; break;
case SONYPI_IOCGBATFLAGS: case SONYPI_IOCGBATFLAGS:
val8 = sonypi_ecrget(SONYPI_BAT_FLAGS) & 0x07; if (ec_read(SONYPI_BAT_FLAGS, &val8)) {
if (copy_to_user((u8 *)arg, &val8, sizeof(val8))) { ret = -EIO;
ret = -EFAULT; break;
goto out;
} }
val8 &= 0x07;
if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
ret = -EFAULT;
break; break;
case SONYPI_IOCGBLUE: case SONYPI_IOCGBLUE:
val8 = sonypi_device.bluetooth_power; val8 = sonypi_device.bluetooth_power;
if (copy_to_user((u8 *)arg, &val8, sizeof(val8))) { if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
ret = -EFAULT; ret = -EFAULT;
goto out;
}
break; break;
case SONYPI_IOCSBLUE: case SONYPI_IOCSBLUE:
if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) { if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
ret = -EFAULT; ret = -EFAULT;
goto out; break;
} }
sonypi_setbluetoothpower(val8); sonypi_setbluetoothpower(val8);
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
out:
up(&sonypi_device.lock); up(&sonypi_device.lock);
return ret; return ret;
} }
...@@ -621,7 +571,7 @@ static struct file_operations sonypi_misc_fops = { ...@@ -621,7 +571,7 @@ static struct file_operations sonypi_misc_fops = {
.poll = sonypi_misc_poll, .poll = sonypi_misc_poll,
.open = sonypi_misc_open, .open = sonypi_misc_open,
.release = sonypi_misc_release, .release = sonypi_misc_release,
.fasync = sonypi_misc_fasync, .fasync = sonypi_misc_fasync,
.ioctl = sonypi_misc_ioctl, .ioctl = sonypi_misc_ioctl,
}; };
...@@ -629,6 +579,51 @@ struct miscdevice sonypi_misc_device = { ...@@ -629,6 +579,51 @@ struct miscdevice sonypi_misc_device = {
-1, "sonypi", &sonypi_misc_fops -1, "sonypi", &sonypi_misc_fops
}; };
#if CONFIG_PM
static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) {
static int old_camera_power;
switch (rqst) {
case PM_SUSPEND:
sonypi_call2(0x81, 0); /* make sure we don't get any more events */
if (camera) {
old_camera_power = sonypi_device.camera_power;
sonypi_camera_off();
}
if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
sonypi_type2_dis();
else
sonypi_type1_dis();
#if !defined(CONFIG_ACPI)
/* disable ACPI mode */
if (fnkeyinit)
outb(0xf1, 0xb2);
#endif
break;
case PM_RESUME:
#if !defined(CONFIG_ACPI)
/* Enable ACPI mode to get Fn key events */
if (fnkeyinit)
outb(0xf0, 0xb2);
#endif
if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
sonypi_type2_srs();
else
sonypi_type1_srs();
sonypi_call1(0x82);
sonypi_call2(0x81, 0xff);
if (compat)
sonypi_call1(0x92);
else
sonypi_call1(0x82);
if (camera && old_camera_power)
sonypi_camera_on();
break;
}
return 0;
}
#endif
static int __devinit sonypi_probe(struct pci_dev *pcidev) { static int __devinit sonypi_probe(struct pci_dev *pcidev) {
int i, ret; int i, ret;
struct sonypi_ioport_list *ioport_list; struct sonypi_ioport_list *ioport_list;
...@@ -720,14 +715,14 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) { ...@@ -720,14 +715,14 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) {
SONYPI_DRIVER_MINORVERSION); SONYPI_DRIVER_MINORVERSION);
printk(KERN_INFO "sonypi: detected %s model, " printk(KERN_INFO "sonypi: detected %s model, "
"verbose = %s, fnkeyinit = %s, camera = %s, " "verbose = %s, fnkeyinit = %s, camera = %s, "
"compat = %s, nojogdial = %s\n", "compat = %s, mask = 0x%08lx\n",
(sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ? (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
"type1" : "type2", "type1" : "type2",
verbose ? "on" : "off", verbose ? "on" : "off",
fnkeyinit ? "on" : "off", fnkeyinit ? "on" : "off",
camera ? "on" : "off", camera ? "on" : "off",
compat ? "on" : "off", compat ? "on" : "off",
nojogdial ? "on" : "off"); mask);
printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
sonypi_device.irq, sonypi_device.irq,
sonypi_device.ioport1, sonypi_device.ioport2); sonypi_device.ioport1, sonypi_device.ioport2);
...@@ -735,6 +730,10 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) { ...@@ -735,6 +730,10 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) {
printk(KERN_INFO "sonypi: device allocated minor is %d\n", printk(KERN_INFO "sonypi: device allocated minor is %d\n",
sonypi_misc_device.minor); sonypi_misc_device.minor);
#if CONFIG_PM
sonypi_device.pm = pm_register(PM_PCI_DEV, 0, sonypi_pm_callback);
#endif
return 0; return 0;
out3: out3:
...@@ -746,6 +745,11 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) { ...@@ -746,6 +745,11 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) {
} }
static void __devexit sonypi_remove(void) { static void __devexit sonypi_remove(void) {
#if CONFIG_PM
pm_unregister(sonypi_device.pm);
#endif
sonypi_call2(0x81, 0); /* make sure we don't get any more events */ sonypi_call2(0x81, 0); /* make sure we don't get any more events */
if (camera) if (camera)
sonypi_camera_off(); sonypi_camera_off();
...@@ -803,7 +807,7 @@ static int __init sonypi_setup(char *str) { ...@@ -803,7 +807,7 @@ static int __init sonypi_setup(char *str) {
compat = ints[5]; compat = ints[5];
if (ints[0] == 5) if (ints[0] == 5)
goto out; goto out;
nojogdial = ints[6]; mask = ints[6];
out: out:
return 1; return 1;
} }
...@@ -815,7 +819,7 @@ __setup("sonypi=", sonypi_setup); ...@@ -815,7 +819,7 @@ __setup("sonypi=", sonypi_setup);
module_init(sonypi_init_module); module_init(sonypi_init_module);
module_exit(sonypi_cleanup_module); module_exit(sonypi_cleanup_module);
MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>"); MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver"); MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -830,7 +834,7 @@ MODULE_PARM(camera,"i"); ...@@ -830,7 +834,7 @@ MODULE_PARM(camera,"i");
MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)"); MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)");
MODULE_PARM(compat,"i"); MODULE_PARM(compat,"i");
MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode"); MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode");
MODULE_PARM(nojogdial, "i"); MODULE_PARM(mask, "i");
MODULE_PARM_DESC(nojogdial, "set this if you have a Vaio without a jogdial (like the fx series)"); MODULE_PARM_DESC(mask, "set this to the mask of event you want to enable (see doc)");
EXPORT_SYMBOL(sonypi_camera_command); EXPORT_SYMBOL(sonypi_camera_command);
/* /*
* Sony Programmable I/O Control Device driver for VAIO * Sony Programmable I/O Control Device driver for VAIO
* *
* Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcve * Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
*
* Copyright (C) 2001-2002 Alcve <www.alcove.com>
* *
* Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
* *
...@@ -35,10 +37,16 @@ ...@@ -35,10 +37,16 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#define SONYPI_DRIVER_MAJORVERSION 1 #define SONYPI_DRIVER_MAJORVERSION 1
#define SONYPI_DRIVER_MINORVERSION 14 #define SONYPI_DRIVER_MINORVERSION 15
#define SONYPI_DEVICE_MODEL_TYPE1 1
#define SONYPI_DEVICE_MODEL_TYPE2 2
#include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pm.h>
#include <linux/acpi.h>
#include "linux/sonypi.h" #include "linux/sonypi.h"
/* type1 models use those */ /* type1 models use those */
...@@ -145,25 +153,23 @@ static struct sonypi_irq_list sonypi_type2_irq_list[] = { ...@@ -145,25 +153,23 @@ static struct sonypi_irq_list sonypi_type2_irq_list[] = {
#define SONYPI_CAMERA_REVISION 8 #define SONYPI_CAMERA_REVISION 8
#define SONYPI_CAMERA_ROMVERSION 9 #define SONYPI_CAMERA_ROMVERSION 9
/* key press event data (ioport2) */ /* Event masks */
#define SONYPI_TYPE1_JOGGER_EV 0x10 #define SONYPI_JOGGER_MASK 0x00000001
#define SONYPI_TYPE2_JOGGER_EV 0x08 #define SONYPI_CAPTURE_MASK 0x00000002
#define SONYPI_TYPE1_CAPTURE_EV 0x60 #define SONYPI_FNKEY_MASK 0x00000004
#define SONYPI_TYPE2_CAPTURE_EV 0x08 #define SONYPI_BLUETOOTH_MASK 0x00000008
#define SONYPI_TYPE1_FNKEY_EV 0x20 #define SONYPI_PKEY_MASK 0x00000010
#define SONYPI_TYPE2_FNKEY_EV 0x08 #define SONYPI_BACK_MASK 0x00000020
#define SONYPI_TYPE1_BLUETOOTH_EV 0x30 #define SONYPI_HELP_MASK 0x00000040
#define SONYPI_TYPE2_BLUETOOTH_EV 0x08 #define SONYPI_LID_MASK 0x00000080
#define SONYPI_TYPE1_PKEY_EV 0x40 #define SONYPI_ZOOM_MASK 0x00000100
#define SONYPI_TYPE2_PKEY_EV 0x08 #define SONYPI_THUMBPHRASE_MASK 0x00000200
#define SONYPI_BACK_EV 0x08 #define SONYPI_MEYE_MASK 0x00000400
#define SONYPI_LID_EV 0x38
struct sonypi_event { struct sonypi_event {
u8 data; u8 data;
u8 event; u8 event;
}; };
/* The set of possible jogger events */ /* The set of possible jogger events */
static struct sonypi_event sonypi_joggerev[] = { static struct sonypi_event sonypi_joggerev[] = {
{ 0x1f, SONYPI_EVENT_JOGDIAL_UP }, { 0x1f, SONYPI_EVENT_JOGDIAL_UP },
...@@ -180,7 +186,7 @@ static struct sonypi_event sonypi_joggerev[] = { ...@@ -180,7 +186,7 @@ static struct sonypi_event sonypi_joggerev[] = {
{ 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED }, { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
{ 0x40, SONYPI_EVENT_JOGDIAL_PRESSED }, { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
{ 0x00, SONYPI_EVENT_JOGDIAL_RELEASED }, { 0x00, SONYPI_EVENT_JOGDIAL_RELEASED },
{ 0x00, 0x00 } { 0, 0 }
}; };
/* The set of possible capture button events */ /* The set of possible capture button events */
...@@ -189,7 +195,7 @@ static struct sonypi_event sonypi_captureev[] = { ...@@ -189,7 +195,7 @@ static struct sonypi_event sonypi_captureev[] = {
{ 0x07, SONYPI_EVENT_CAPTURE_PRESSED }, { 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
{ 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED }, { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
{ 0x00, SONYPI_EVENT_CAPTURE_RELEASED }, { 0x00, SONYPI_EVENT_CAPTURE_RELEASED },
{ 0x00, 0x00 } { 0, 0 }
}; };
/* The set of possible fnkeys events */ /* The set of possible fnkeys events */
...@@ -215,7 +221,7 @@ static struct sonypi_event sonypi_fnkeyev[] = { ...@@ -215,7 +221,7 @@ static struct sonypi_event sonypi_fnkeyev[] = {
{ 0x34, SONYPI_EVENT_FNKEY_S }, { 0x34, SONYPI_EVENT_FNKEY_S },
{ 0x35, SONYPI_EVENT_FNKEY_B }, { 0x35, SONYPI_EVENT_FNKEY_B },
{ 0x36, SONYPI_EVENT_FNKEY_ONLY }, { 0x36, SONYPI_EVENT_FNKEY_ONLY },
{ 0x00, 0x00 } { 0, 0 }
}; };
/* The set of possible program key events */ /* The set of possible program key events */
...@@ -223,7 +229,7 @@ static struct sonypi_event sonypi_pkeyev[] = { ...@@ -223,7 +229,7 @@ static struct sonypi_event sonypi_pkeyev[] = {
{ 0x01, SONYPI_EVENT_PKEY_P1 }, { 0x01, SONYPI_EVENT_PKEY_P1 },
{ 0x02, SONYPI_EVENT_PKEY_P2 }, { 0x02, SONYPI_EVENT_PKEY_P2 },
{ 0x04, SONYPI_EVENT_PKEY_P3 }, { 0x04, SONYPI_EVENT_PKEY_P3 },
{ 0x00, 0x00 } { 0, 0 }
}; };
/* The set of possible bluetooth events */ /* The set of possible bluetooth events */
...@@ -231,21 +237,74 @@ static struct sonypi_event sonypi_blueev[] = { ...@@ -231,21 +237,74 @@ static struct sonypi_event sonypi_blueev[] = {
{ 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED }, { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
{ 0x59, SONYPI_EVENT_BLUETOOTH_ON }, { 0x59, SONYPI_EVENT_BLUETOOTH_ON },
{ 0x5a, SONYPI_EVENT_BLUETOOTH_OFF }, { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
{ 0x00, 0x00 } { 0, 0 }
}; };
/* The set of possible back button events */ /* The set of possible back button events */
static struct sonypi_event sonypi_backev[] = { static struct sonypi_event sonypi_backev[] = {
{ 0x20, SONYPI_EVENT_BACK_PRESSED }, { 0x20, SONYPI_EVENT_BACK_PRESSED },
{ 0, 0 }
};
/* The set of possible help button events */
static struct sonypi_event sonypi_helpev[] = {
{ 0x3b, SONYPI_EVENT_HELP_PRESSED }, { 0x3b, SONYPI_EVENT_HELP_PRESSED },
{ 0x00, 0x00 } { 0, 0 }
}; };
/* The set of possible lid events */ /* The set of possible lid events */
static struct sonypi_event sonypi_lidev[] = { static struct sonypi_event sonypi_lidev[] = {
{ 0x51, SONYPI_EVENT_LID_CLOSED }, { 0x51, SONYPI_EVENT_LID_CLOSED },
{ 0x50, SONYPI_EVENT_LID_OPENED }, { 0x50, SONYPI_EVENT_LID_OPENED },
{ 0x00, 0x00 } { 0, 0 }
};
/* The set of possible zoom events */
static struct sonypi_event sonypi_zoomev[] = {
{ 0x3a, SONYPI_EVENT_ZOOM_PRESSED },
{ 0, 0 }
};
/* The set of possible thumbphrase events */
static struct sonypi_event sonypi_thumbphraseev[] = {
{ 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
{ 0, 0 }
};
/* The set of possible motioneye camera events */
static struct sonypi_event sonypi_meyeev[] = {
{ 0x00, SONYPI_EVENT_MEYE_FACE },
{ 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
{ 0, 0 }
};
struct sonypi_eventtypes {
int model;
u8 data;
unsigned long mask;
struct sonypi_event * events;
} sonypi_eventtypes[] = {
{ SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
{ SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
{ SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
{ SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_JOGGER_MASK, sonypi_joggerev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_CAPTURE_MASK, sonypi_captureev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_BACK_MASK, sonypi_backev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_ZOOM_MASK, sonypi_zoomev },
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
{ 0, 0, 0, 0 }
}; };
#define SONYPI_BUF_SIZE 128 #define SONYPI_BUF_SIZE 128
...@@ -259,9 +318,6 @@ struct sonypi_queue { ...@@ -259,9 +318,6 @@ struct sonypi_queue {
unsigned char buf[SONYPI_BUF_SIZE]; unsigned char buf[SONYPI_BUF_SIZE];
}; };
#define SONYPI_DEVICE_MODEL_TYPE1 1
#define SONYPI_DEVICE_MODEL_TYPE2 2
struct sonypi_device { struct sonypi_device {
struct pci_dev *dev; struct pci_dev *dev;
u16 irq; u16 irq;
...@@ -275,16 +331,47 @@ struct sonypi_device { ...@@ -275,16 +331,47 @@ struct sonypi_device {
struct sonypi_queue queue; struct sonypi_queue queue;
int open_count; int open_count;
int model; int model;
#if CONFIG_PM
struct pm_dev *pm;
#endif
}; };
#define wait_on_command(quiet, command) { \ #define ITERATIONS_LONG 10000
unsigned int n = 10000; \ #define ITERATIONS_SHORT 10
#define wait_on_command(quiet, command, iterations) { \
unsigned int n = iterations; \
while (--n && (command)) \ while (--n && (command)) \
udelay(1); \ udelay(1); \
if (!n && (verbose || !quiet)) \ if (!n && (verbose || !quiet)) \
printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \ printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \
} }
#if !defined(CONFIG_ACPI)
extern int verbose;
static inline int ec_write(u8 addr, u8 value) {
wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
outb_p(0x81, SONYPI_CST_IOPORT);
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
outb_p(addr, SONYPI_DATA_IOPORT);
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
outb_p(value, SONYPI_DATA_IOPORT);
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
return 0;
}
static inline int ec_read(u8 addr, u8 *value) {
wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
outb_p(0x80, SONYPI_CST_IOPORT);
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
outb_p(addr, SONYPI_DATA_IOPORT);
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
*value = inb_p(SONYPI_DATA_IOPORT);
return 0;
}
#endif /* !CONFIG_ACPI */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _SONYPI_PRIV_H_ */ #endif /* _SONYPI_PRIV_H_ */
#
# Character device configuration
#
menu "Watchdog Cards"
config WATCHDOG
bool "Watchdog Timer Support"
---help---
If you say Y here (and to one of the following options) and create a
character special file /dev/watchdog with major number 10 and minor
number 130 using mknod ("man mknod"), you will get a watchdog, i.e.:
subsequently opening the file and then failing to write to it for
longer than 1 minute will result in rebooting the machine. This
could be useful for a networked machine that needs to come back
online as fast as possible after a lock-up. There's both a watchdog
implementation entirely in software (which can sometimes fail to
reboot the machine) and a driver for hardware watchdog boards, which
are more robust and can also keep track of the temperature inside
your computer. For details, read <file:Documentation/watchdog.txt>
in the kernel source.
The watchdog is usually used together with the watchdog daemon
which is available from
<ftp://ibiblio.org/pub/Linux/system/daemons/watchdog/>. This daemon can
also monitor NFS connections and can reboot the machine when the process
table is full.
If unsure, say N.
config WATCHDOG_NOWAYOUT
bool "Disable watchdog shutdown on close"
depends on WATCHDOG
help
The default watchdog behaviour (which you get if you say N here) is
to stop the timer if the process managing it closes the file
/dev/watchdog. It's always remotely possible that this process might
get killed. If you say Y here, the watchdog cannot be stopped once
it has been started.
config SOFT_WATCHDOG
tristate "Software watchdog"
depends on WATCHDOG
help
A software monitoring watchdog. This will fail to reboot your system
from some situations that the hardware watchdog will recover
from. Equally it's a lot cheaper to install.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. The module will be called
softdog.o.
config WDT
tristate "WDT Watchdog timer"
depends on WATCHDOG
---help---
If you have a WDT500P or WDT501P watchdog board, say Y here,
otherwise N. It is not possible to probe for this board, which means
that you have to inform the kernel about the IO port and IRQ using
the "wdt=" kernel option (try "man bootparam" or see the
documentation of your boot loader (lilo or loadlin) about how to
pass options to the kernel at boot time).
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called wdt.o.
config WDTPCI
tristate "WDT PCI Watchdog timer"
depends on WATCHDOG
---help---
If you have a PCI WDT500/501 watchdog board, say Y here, otherwise
N. It is not possible to probe for this board, which means that you
have to inform the kernel about the IO port and IRQ using the "wdt="
kernel option (try "man bootparam" or see the documentation of your
boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time).
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called wdt_pci.o.
config WDT_501
bool "WDT501 features"
depends on WDT
help
Saying Y here and creating a character special file /dev/temperature
with major number 10 and minor number 131 ("man mknod") will give
you a thermometer inside your computer: reading from
/dev/temperature yields one byte, the temperature in degrees
Fahrenheit. This works only if you have a WDT501P watchdog board
installed.
config WDT_501_FAN
bool "Fan Tachometer"
depends on WDT_501
help
Enable the Fan Tachometer on the WDT501. Only do this if you have a
fan tachometer actually set up.
config PCWATCHDOG
tristate "Berkshire Products PC Watchdog"
depends on WATCHDOG
---help---
This is the driver for the Berkshire Products PC Watchdog card.
This card simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
time. This driver is like the WDT501 driver but for different
hardware. Please read <file:Documentation/pcwd-watchdog.txt>. The PC
watchdog cards can be ordered from <http://www.berkprod.com/>.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called pcwd.o. If you want to compile it as a module,
say M here and read <file:Documentation/modules.txt>.
Most people will say N.
config ACQUIRE_WDT
tristate "Acquire SBC Watchdog Timer"
depends on WATCHDOG
---help---
This is the driver for the hardware watchdog on the PSC-6x86 Single
Board Computer produced by Acquire Inc (and others). This watchdog
simply watches your kernel to make sure it doesn't freeze, and if
it does, it reboots your computer after a certain amount of time.
This driver is like the WDT501 driver but for different hardware.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called pscwdt.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. Most
people will say N.
config ADVANTECH_WDT
tristate "Advantech SBC Watchdog Timer"
depends on WATCHDOG
help
If you are configuring a Linux kernel for the Advantech single-board
computer, say `Y' here to support its built-in watchdog timer
feature. See the help for CONFIG_WATCHDOG for discussion.
config 21285_WATCHDOG
tristate "DC21285 watchdog"
depends on WATCHDOG && FOOTBRIDGE
help
The Intel Footbridge chip contains a builtin watchdog circuit. Say Y
here if you wish to use this. Alternatively say M to compile the
driver as a module, which will be called wdt285.o.
This driver does not work on all machines. In particular, early CATS
boards have hardware problems that will cause the machine to simply
lock up if the watchdog fires.
"If in doubt, leave it out" - say N.
config 977_WATCHDOG
tristate "NetWinder WB83C977 watchdog"
depends on WATCHDOG && FOOTBRIDGE && ARCH_NETWINDER
help
Say Y here to include support for the WB977 watchdog included in
NetWinder machines. Alternatively say M to compile the driver as
a module, which will be called wdt977.o.
Not sure? It's safe to say N.
config EUROTECH_WDT
tristate "Eurotech CPU-1220/1410 Watchdog Timer"
depends on WATCHDOG
help
Enable support for the watchdog timer on the Eurotech CPU-1220 and
CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product
information are at <http://www.eurotech.it/>.
config IB700_WDT
tristate "IB700 SBC Watchdog Timer"
depends on WATCHDOG
---help---
This is the driver for the hardware watchdog on the IB700 Single
Board Computer produced by TMC Technology (www.tmc-uk.com). This watchdog
simply watches your kernel to make sure it doesn't freeze, and if
it does, it reboots your computer after a certain amount of time.
This driver is like the WDT501 driver but for slightly different hardware.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called ib700wdt.o. If you want to compile it as a
module, say M here and read Documentation/modules.txt. Most people
will say N.
config I810_TCO
tristate "Intel i810 TCO timer / Watchdog"
depends on WATCHDOG
---help---
Hardware driver for the TCO timer built into the Intel i810 and i815
chipset family. The TCO (Total Cost of Ownership) timer is a
watchdog timer that will reboot the machine after its second
expiration. The expiration time can be configured by commandline
argument "i810_margin=<n>" where <n> is the counter initial value.
It is decremented every 0.6 secs, the default is 50 which gives a
timeout of 30 seconds and one minute until reset.
On some motherboards the driver may fail to reset the chipset's
NO_REBOOT flag which prevents the watchdog from rebooting the
machine. If this is the case you will get a kernel message like
"i810tco init: failed to reset NO_REBOOT flag".
If you want to compile this as a module, say M and read
<file:Documentation/modules.txt>. The module will be called
i810-tco.o.
config MIXCOMWD
tristate "Mixcom Watchdog"
depends on WATCHDOG
---help---
This is a driver for the Mixcom hardware watchdog cards. This
watchdog simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
time.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called mixcomwd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. Most
people will say N.
config SCx200_WDT
tristate "NatSemi SCx200 Watchdog"
depends on WATCHDOG
help
Enable the built-in watchdog timer support on the National
Semiconductor SCx200 processors.
If compiled as a module, it will be called scx200_watchdog.o.
config 60XX_WDT
tristate "SBC-60XX Watchdog Timer"
depends on WATCHDOG
help
This driver can be used with the watchdog timer found on some
single board computers, namely the 6010 PII based computer.
It may well work with other cards. It reads port 0x443 to enable
and re-set the watchdog timer, and reads port 0x45 to disable
the watchdog. If you have a card that behave in similar ways,
you can probably make this driver work with your card as well.
You can compile this driver directly into the kernel, or use
it as a module. The module will be called sbc60xxwdt.o.
config W83877F_WDT
tristate "W83877F (EMACS) Watchdog Timer"
depends on WATCHDOG
---help---
This is the driver for the hardware watchdog on the W83877F chipset
as used in EMACS PC-104 motherboards (and likely others). This
watchdog simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
time.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called mixcomwd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. Most
people will say N.
config MACHZ_WDT
tristate "ZF MachZ Watchdog"
depends on WATCHDOG
---help---
If you are using a ZF Micro MachZ processor, say Y here, otherwise
N. This is the driver for the watchdog timer builtin on that
processor using ZF-Logic interface. This watchdog simply watches
your kernel to make sure it doesn't freeze, and if it does, it
reboots your computer after a certain amount of time.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called machzwd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
endmenu
#
# Makefile for the kernel character device drivers.
#
# Only one watchdog can succeed. We probe the hardware watchdog
# drivers first, then the softdog driver. This means if your hardware
# watchdog dies or is 'borrowed' for some reason the software watchdog
# still gives you some cover.
watchdog-$(CONFIG_PCWATCHDOG) += pcwd.o
watchdog-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
watchdog-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
watchdog-$(CONFIG_IB700_WDT) += ib700wdt.o
watchdog-$(CONFIG_MIXCOMWD) += mixcomwd.o
watchdog-$(CONFIG_SCx200_WDT) += scx200_wdt.o
watchdog-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
watchdog-$(CONFIG_WDT) += wdt.o
watchdog-$(CONFIG_WDTPCI) += wdt_pci.o
watchdog-$(CONFIG_21285_WATCHDOG) += wdt285.o
watchdog-$(CONFIG_977_WATCHDOG) += wdt977.o
watchdog-$(CONFIG_I810_TCO) += i810-tco.o
watchdog-$(CONFIG_MACHZ_WDT) += machzwd.o
watchdog-$(CONFIG_SH_WDT) += shwdt.o
watchdog-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
watchdog-$(CONFIG_SOFT_WATCHDOG) += softdog.o
include $(TOPDIR)/Rules.make
...@@ -411,8 +411,8 @@ static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev) ...@@ -411,8 +411,8 @@ static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
* Update the bridge resources of the bridge to accommodate devices * Update the bridge resources of the bridge to accommodate devices
* behind it. * behind it.
*/ */
pbus_size_bridges(child); pci_bus_size_bridges(child);
pbus_assign_resources(child); pci_bus_assign_resources(child);
/* Enable resource mapping via command register */ /* Enable resource mapping via command register */
command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
......
/* /*
* Motion Eye video4linux driver for Sony Vaio PictureBook * Motion Eye video4linux driver for Sony Vaio PictureBook
* *
* Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcve * Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
*
* Copyright (C) 2001-2002 Alcve <www.alcove.com>
* *
* Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
* *
...@@ -169,16 +171,28 @@ static int ptable_alloc(void) { ...@@ -169,16 +171,28 @@ static int ptable_alloc(void) {
meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev, meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev,
PAGE_SIZE, PAGE_SIZE,
&meye.mchip_dmahandle); &meye.mchip_dmahandle);
if (!meye.mchip_ptable[MCHIP_NB_PAGES]) if (!meye.mchip_ptable[MCHIP_NB_PAGES]) {
meye.mchip_dmahandle = 0;
return -1; return -1;
}
pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
for (i = 0; i < MCHIP_NB_PAGES; i++) { for (i = 0; i < MCHIP_NB_PAGES; i++) {
meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev, meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev,
PAGE_SIZE, PAGE_SIZE,
pt); pt);
if (!meye.mchip_ptable[i]) if (!meye.mchip_ptable[i]) {
int j;
pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
for (j = 0; j < i; ++j) {
pci_free_consistent(meye.mchip_dev,
PAGE_SIZE,
meye.mchip_ptable[j], *pt);
pt++;
}
meye.mchip_dmahandle = 0;
return -1; return -1;
}
pt++; pt++;
} }
return 0; return 0;
...@@ -189,11 +203,13 @@ static void ptable_free(void) { ...@@ -189,11 +203,13 @@ static void ptable_free(void) {
int i; int i;
pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
for (i = 0; i < MCHIP_NB_PAGES; i++) for (i = 0; i < MCHIP_NB_PAGES; i++) {
if (meye.mchip_ptable[i]) if (meye.mchip_ptable[i])
pci_free_consistent(meye.mchip_dev, pci_free_consistent(meye.mchip_dev,
PAGE_SIZE, PAGE_SIZE,
meye.mchip_ptable[i], *pt); meye.mchip_ptable[i], *pt);
pt++;
}
if (meye.mchip_ptable[MCHIP_NB_PAGES]) if (meye.mchip_ptable[MCHIP_NB_PAGES])
pci_free_consistent(meye.mchip_dev, pci_free_consistent(meye.mchip_dev,
...@@ -569,6 +585,16 @@ static void mchip_vrj_setup(u8 mode) { ...@@ -569,6 +585,16 @@ static void mchip_vrj_setup(u8 mode) {
mchip_load_tables(); mchip_load_tables();
} }
/* sets the DMA parameters into the chip */
static void mchip_dma_setup(u32 dma_addr) {
int i;
mchip_set(MCHIP_MM_PT_ADDR, dma_addr);
for (i = 0; i < 4; i++)
mchip_set(MCHIP_MM_FIR(i), 0);
meye.mchip_fnum = 0;
}
/* setup for DMA transfers - also zeros the framebuffer */ /* setup for DMA transfers - also zeros the framebuffer */
static int mchip_dma_alloc(void) { static int mchip_dma_alloc(void) {
if (!meye.mchip_dmahandle) if (!meye.mchip_dmahandle)
...@@ -579,18 +605,10 @@ static int mchip_dma_alloc(void) { ...@@ -579,18 +605,10 @@ static int mchip_dma_alloc(void) {
/* frees the DMA buffer */ /* frees the DMA buffer */
static void mchip_dma_free(void) { static void mchip_dma_free(void) {
if (meye.mchip_dmahandle) if (meye.mchip_dmahandle) {
mchip_dma_setup(0);
ptable_free(); ptable_free();
} }
/* sets the DMA parameters into the chip */
static void mchip_dma_setup(void) {
int i;
mchip_set(MCHIP_MM_PT_ADDR, meye.mchip_dmahandle);
for (i = 0; i < 4; i++)
mchip_set(MCHIP_MM_FIR(i), 0);
meye.mchip_fnum = 0;
} }
/* stop any existing HIC action and wait for any dma to complete then /* stop any existing HIC action and wait for any dma to complete then
...@@ -698,7 +716,7 @@ static void mchip_take_picture(void) { ...@@ -698,7 +716,7 @@ static void mchip_take_picture(void) {
mchip_hic_stop(); mchip_hic_stop();
mchip_subsample(); mchip_subsample();
mchip_dma_setup(); mchip_dma_setup(meye.mchip_dmahandle);
mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP); mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
...@@ -741,7 +759,7 @@ static void mchip_continuous_start(void) { ...@@ -741,7 +759,7 @@ static void mchip_continuous_start(void) {
mchip_hic_stop(); mchip_hic_stop();
mchip_subsample(); mchip_subsample();
mchip_set_framerate(); mchip_set_framerate();
mchip_dma_setup(); mchip_dma_setup(meye.mchip_dmahandle);
meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT; meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
...@@ -801,7 +819,7 @@ static void mchip_cont_compression_start(void) { ...@@ -801,7 +819,7 @@ static void mchip_cont_compression_start(void) {
mchip_vrj_setup(0x3f); mchip_vrj_setup(0x3f);
mchip_subsample(); mchip_subsample();
mchip_set_framerate(); mchip_set_framerate();
mchip_dma_setup(); mchip_dma_setup(meye.mchip_dmahandle);
meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
...@@ -823,7 +841,7 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) { ...@@ -823,7 +841,7 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
while (1) { while (1) {
v = mchip_get_frame(); v = mchip_get_frame();
if (!(v & MCHIP_MM_FIR_RDY)) if (!(v & MCHIP_MM_FIR_RDY))
goto out; return;
switch (meye.mchip_mode) { switch (meye.mchip_mode) {
case MCHIP_HIC_MODE_CONT_OUT: case MCHIP_HIC_MODE_CONT_OUT:
...@@ -856,12 +874,11 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) { ...@@ -856,12 +874,11 @@ static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
default: default:
/* do not free frame, since it can be a snap */ /* do not free frame, since it can be a snap */
goto out; return;
} /* switch */ } /* switch */
mchip_free_frame(); mchip_free_frame();
} }
out:
} }
/****************************************************************************/ /****************************************************************************/
...@@ -889,6 +906,7 @@ static int meye_open(struct inode *inode, struct file *file) { ...@@ -889,6 +906,7 @@ static int meye_open(struct inode *inode, struct file *file) {
static int meye_release(struct inode *inode, struct file *file) { static int meye_release(struct inode *inode, struct file *file) {
mchip_hic_stop(); mchip_hic_stop();
mchip_dma_free();
video_exclusive_release(inode,file); video_exclusive_release(inode,file);
return 0; return 0;
} }
...@@ -957,7 +975,6 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, ...@@ -957,7 +975,6 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
case VIDIOCSYNC: { case VIDIOCSYNC: {
int *i = arg; int *i = arg;
DECLARE_WAITQUEUE(wait, current);
if (*i < 0 || *i >= gbuffers) if (*i < 0 || *i >= gbuffers)
return -EINVAL; return -EINVAL;
...@@ -967,18 +984,9 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, ...@@ -967,18 +984,9 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
case MEYE_BUF_UNUSED: case MEYE_BUF_UNUSED:
return -EINVAL; return -EINVAL;
case MEYE_BUF_USING: case MEYE_BUF_USING:
add_wait_queue(&meye.grabq.proc_list, &wait); if (wait_event_interruptible(meye.grabq.proc_list,
current->state = TASK_INTERRUPTIBLE; (meye.grab_buffer[*i].state != MEYE_BUF_USING)))
while (meye.grab_buffer[*i].state == MEYE_BUF_USING) { return -EINTR;
schedule();
if(signal_pending(current)) {
remove_wait_queue(&meye.grabq.proc_list, &wait);
current->state = TASK_RUNNING;
return -EINTR;
}
}
remove_wait_queue(&meye.grabq.proc_list, &wait);
current->state = TASK_RUNNING;
/* fall through */ /* fall through */
case MEYE_BUF_DONE: case MEYE_BUF_DONE:
meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
...@@ -1095,7 +1103,6 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, ...@@ -1095,7 +1103,6 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
case MEYEIOC_SYNC: { case MEYEIOC_SYNC: {
int *i = arg; int *i = arg;
DECLARE_WAITQUEUE(wait, current);
if (*i < 0 || *i >= gbuffers) if (*i < 0 || *i >= gbuffers)
return -EINVAL; return -EINVAL;
...@@ -1105,18 +1112,9 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, ...@@ -1105,18 +1112,9 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
case MEYE_BUF_UNUSED: case MEYE_BUF_UNUSED:
return -EINVAL; return -EINVAL;
case MEYE_BUF_USING: case MEYE_BUF_USING:
add_wait_queue(&meye.grabq.proc_list, &wait); if (wait_event_interruptible(meye.grabq.proc_list,
current->state = TASK_INTERRUPTIBLE; (meye.grab_buffer[*i].state != MEYE_BUF_USING)))
while (meye.grab_buffer[*i].state == MEYE_BUF_USING) { return -EINTR;
schedule();
if(signal_pending(current)) {
remove_wait_queue(&meye.grabq.proc_list, &wait);
current->state = TASK_RUNNING;
return -EINTR;
}
}
remove_wait_queue(&meye.grabq.proc_list, &wait);
current->state = TASK_RUNNING;
/* fall through */ /* fall through */
case MEYE_BUF_DONE: case MEYE_BUF_DONE:
meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
...@@ -1211,20 +1209,20 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) { ...@@ -1211,20 +1209,20 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) {
} }
static struct file_operations meye_fops = { static struct file_operations meye_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
open: meye_open, .open = meye_open,
release: meye_release, .release = meye_release,
mmap: meye_mmap, .mmap = meye_mmap,
ioctl: meye_ioctl, .ioctl = meye_ioctl,
llseek: no_llseek, .llseek = no_llseek,
}; };
static struct video_device meye_template = { static struct video_device meye_template = {
owner: THIS_MODULE, .owner = THIS_MODULE,
name: "meye", .name = "meye",
type: VID_TYPE_CAPTURE, .type = VID_TYPE_CAPTURE,
hardware: VID_HARDWARE_MEYE, .hardware = VID_HARDWARE_MEYE,
fops: &meye_fops, .fops = &meye_fops,
}; };
static int __devinit meye_probe(struct pci_dev *pcidev, static int __devinit meye_probe(struct pci_dev *pcidev,
...@@ -1244,15 +1242,9 @@ static int __devinit meye_probe(struct pci_dev *pcidev, ...@@ -1244,15 +1242,9 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
meye.mchip_dev = pcidev; meye.mchip_dev = pcidev;
memcpy(&meye.video_dev, &meye_template, sizeof(meye_template)); memcpy(&meye.video_dev, &meye_template, sizeof(meye_template));
if (mchip_dma_alloc()) {
printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
ret = -ENOMEM;
goto out2;
}
if ((ret = pci_enable_device(meye.mchip_dev))) { if ((ret = pci_enable_device(meye.mchip_dev))) {
printk(KERN_ERR "meye: pci_enable_device failed\n"); printk(KERN_ERR "meye: pci_enable_device failed\n");
goto out3; goto out2;
} }
meye.mchip_irq = pcidev->irq; meye.mchip_irq = pcidev->irq;
...@@ -1260,14 +1252,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev, ...@@ -1260,14 +1252,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
if (!mchip_adr) { if (!mchip_adr) {
printk(KERN_ERR "meye: mchip has no device base address\n"); printk(KERN_ERR "meye: mchip has no device base address\n");
ret = -EIO; ret = -EIO;
goto out4; goto out3;
} }
if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0), if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
pci_resource_len(meye.mchip_dev, 0), pci_resource_len(meye.mchip_dev, 0),
"meye")) { "meye")) {
ret = -EIO; ret = -EIO;
printk(KERN_ERR "meye: request_mem_region failed\n"); printk(KERN_ERR "meye: request_mem_region failed\n");
goto out4; goto out3;
} }
pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision); pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision);
...@@ -1280,14 +1272,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev, ...@@ -1280,14 +1272,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
if ((ret = request_irq(meye.mchip_irq, meye_irq, if ((ret = request_irq(meye.mchip_irq, meye_irq,
SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq))) { SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq))) {
printk(KERN_ERR "meye: request_irq failed (ret=%d)\n", ret); printk(KERN_ERR "meye: request_irq failed (ret=%d)\n", ret);
goto out5; goto out4;
} }
meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS); meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
if (!meye.mchip_mmregs) { if (!meye.mchip_mmregs) {
printk(KERN_ERR "meye: ioremap failed\n"); printk(KERN_ERR "meye: ioremap failed\n");
ret = -EIO; ret = -EIO;
goto out6; goto out5;
} }
/* Ask the camera to perform a soft reset. */ /* Ask the camera to perform a soft reset. */
...@@ -1309,7 +1301,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev, ...@@ -1309,7 +1301,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
printk(KERN_ERR "meye: video_register_device failed\n"); printk(KERN_ERR "meye: video_register_device failed\n");
ret = -EIO; ret = -EIO;
goto out7; goto out6;
} }
printk(KERN_INFO "meye: Motion Eye Camera Driver v%d.%d.\n", printk(KERN_INFO "meye: Motion Eye Camera Driver v%d.%d.\n",
...@@ -1343,17 +1335,15 @@ static int __devinit meye_probe(struct pci_dev *pcidev, ...@@ -1343,17 +1335,15 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48); sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48);
return 0; return 0;
out7:
iounmap(meye.mchip_mmregs);
out6: out6:
free_irq(meye.mchip_irq, meye_irq); iounmap(meye.mchip_mmregs);
out5: out5:
free_irq(meye.mchip_irq, meye_irq);
out4:
release_mem_region(pci_resource_start(meye.mchip_dev, 0), release_mem_region(pci_resource_start(meye.mchip_dev, 0),
pci_resource_len(meye.mchip_dev, 0)); pci_resource_len(meye.mchip_dev, 0));
out4:
pci_disable_device(meye.mchip_dev);
out3: out3:
mchip_dma_free(); pci_disable_device(meye.mchip_dev);
out2: out2:
sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0); sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
out1: out1:
...@@ -1371,7 +1361,6 @@ static void __devexit meye_remove(struct pci_dev *pcidev) { ...@@ -1371,7 +1361,6 @@ static void __devexit meye_remove(struct pci_dev *pcidev) {
free_irq(meye.mchip_irq, meye_irq); free_irq(meye.mchip_irq, meye_irq);
iounmap(meye.mchip_mmregs); iounmap(meye.mchip_mmregs);
release_mem_region(pci_resource_start(meye.mchip_dev, 0), release_mem_region(pci_resource_start(meye.mchip_dev, 0),
...@@ -1398,10 +1387,10 @@ static struct pci_device_id meye_pci_tbl[] __devinitdata = { ...@@ -1398,10 +1387,10 @@ static struct pci_device_id meye_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, meye_pci_tbl); MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
static struct pci_driver meye_driver = { static struct pci_driver meye_driver = {
name: "meye", .name = "meye",
id_table: meye_pci_tbl, .id_table = meye_pci_tbl,
probe: meye_probe, .probe = meye_probe,
remove: __devexit_p(meye_remove), .remove = __devexit_p(meye_remove),
}; };
static int __init meye_init_module(void) { static int __init meye_init_module(void) {
...@@ -1441,7 +1430,7 @@ static int __init meye_setup(char *str) { ...@@ -1441,7 +1430,7 @@ static int __init meye_setup(char *str) {
__setup("meye=", meye_setup); __setup("meye=", meye_setup);
#endif #endif
MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>"); MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
MODULE_DESCRIPTION("video4linux driver for the MotionEye camera"); MODULE_DESCRIPTION("video4linux driver for the MotionEye camera");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
/* /*
* Motion Eye video4linux driver for Sony Vaio PictureBook * Motion Eye video4linux driver for Sony Vaio PictureBook
* *
* Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcve * Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
*
* Copyright (C) 2001-2002 Alcve <www.alcove.com>
* *
* Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
* *
...@@ -29,7 +31,7 @@ ...@@ -29,7 +31,7 @@
#define _MEYE_PRIV_H_ #define _MEYE_PRIV_H_
#define MEYE_DRIVER_MAJORVERSION 1 #define MEYE_DRIVER_MAJORVERSION 1
#define MEYE_DRIVER_MINORVERSION 4 #define MEYE_DRIVER_MINORVERSION 5
/****************************************************************************/ /****************************************************************************/
/* Motion JPEG chip registers */ /* Motion JPEG chip registers */
......
...@@ -333,13 +333,13 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) ...@@ -333,13 +333,13 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
} }
void __devinit void __devinit
pbus_size_bridges(struct pci_bus *bus) pci_bus_size_bridges(struct pci_bus *bus)
{ {
struct list_head *ln; struct list_head *ln;
unsigned long mask, type; unsigned long mask, type;
for (ln=bus->children.next; ln != &bus->children; ln=ln->next) for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
pbus_size_bridges(pci_bus_b(ln)); pci_bus_size_bridges(pci_bus_b(ln));
/* The root bus? */ /* The root bus? */
if (!bus->self) if (!bus->self)
...@@ -358,10 +358,10 @@ pbus_size_bridges(struct pci_bus *bus) ...@@ -358,10 +358,10 @@ pbus_size_bridges(struct pci_bus *bus)
} }
pbus_size_mem(bus, mask, type); pbus_size_mem(bus, mask, type);
} }
EXPORT_SYMBOL(pbus_size_bridges); EXPORT_SYMBOL(pci_bus_size_bridges);
void __devinit void __devinit
pbus_assign_resources(struct pci_bus *bus) pci_bus_assign_resources(struct pci_bus *bus)
{ {
struct list_head *ln; struct list_head *ln;
int found_vga = pbus_assign_resources_sorted(bus); int found_vga = pbus_assign_resources_sorted(bus);
...@@ -377,11 +377,11 @@ pbus_assign_resources(struct pci_bus *bus) ...@@ -377,11 +377,11 @@ pbus_assign_resources(struct pci_bus *bus)
for (ln=bus->children.next; ln != &bus->children; ln=ln->next) { for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
struct pci_bus *b = pci_bus_b(ln); struct pci_bus *b = pci_bus_b(ln);
pbus_assign_resources(b); pci_bus_assign_resources(b);
pci_setup_bridge(b); pci_setup_bridge(b);
} }
} }
EXPORT_SYMBOL(pbus_assign_resources); EXPORT_SYMBOL(pci_bus_assign_resources);
void __init void __init
pci_assign_unassigned_resources(void) pci_assign_unassigned_resources(void)
...@@ -392,10 +392,10 @@ pci_assign_unassigned_resources(void) ...@@ -392,10 +392,10 @@ pci_assign_unassigned_resources(void)
/* Depth first, calculate sizes and alignments of all /* Depth first, calculate sizes and alignments of all
subordinate buses. */ subordinate buses. */
for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
pbus_size_bridges(pci_bus_b(ln)); pci_bus_size_bridges(pci_bus_b(ln));
/* Depth last, allocate resources and update the hardware. */ /* Depth last, allocate resources and update the hardware. */
for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
pbus_assign_resources(pci_bus_b(ln)); pci_bus_assign_resources(pci_bus_b(ln));
pci_for_each_dev(dev) { pci_for_each_dev(dev) {
pdev_enable_device(dev); pdev_enable_device(dev);
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#include <linux/intermezzo_fs.h> #include <linux/intermezzo_fs.h>
static kmem_cache_t * presto_dentry_slab; kmem_cache_t * presto_dentry_slab;
/* called when a cache lookup succeeds */ /* called when a cache lookup succeeds */
static int presto_d_revalidate(struct dentry *de, int flag) static int presto_d_revalidate(struct dentry *de, int flag)
......
...@@ -297,11 +297,20 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, ...@@ -297,11 +297,20 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
return -EINVAL; return -EINVAL;
} }
if (((start += l->l_start) < 0) || (l->l_len < 0)) /* POSIX-1996 leaves the case l->l_len < 0 undefined;
return -EINVAL; POSIX-2001 defines it. */
start += l->l_start;
end = start + l->l_len - 1; end = start + l->l_len - 1;
if (l->l_len < 0) {
end = start - 1;
start += l->l_len;
}
if (start < 0)
return -EINVAL;
if (l->l_len > 0 && end < 0) if (l->l_len > 0 && end < 0)
return -EOVERFLOW; return -EOVERFLOW;
fl->fl_start = start; /* we record the absolute position */ fl->fl_start = start; /* we record the absolute position */
fl->fl_end = end; fl->fl_end = end;
if (l->l_len == 0) if (l->l_len == 0)
......
...@@ -65,11 +65,6 @@ nfs4_setup_compound(struct nfs4_compound *cp, struct nfs4_op *ops, ...@@ -65,11 +65,6 @@ nfs4_setup_compound(struct nfs4_compound *cp, struct nfs4_op *ops,
memset(cp, 0, sizeof(*cp)); memset(cp, 0, sizeof(*cp));
cp->ops = ops; cp->ops = ops;
cp->server = server; cp->server = server;
#if NFS4_DEBUG
cp->taglen = strlen(tag);
cp->tag = tag;
#endif
} }
static void static void
...@@ -373,6 +368,7 @@ nfs4_setup_open(struct nfs4_compound *cp, int flags, struct qstr *name, ...@@ -373,6 +368,7 @@ nfs4_setup_open(struct nfs4_compound *cp, int flags, struct qstr *name,
BUG_ON(cp->flags); BUG_ON(cp->flags);
open->op_client_state = cp->server->nfs4_state;
open->op_share_access = flags & 3; open->op_share_access = flags & 3;
open->op_opentype = (flags & O_CREAT) ? NFS4_OPEN_CREATE : NFS4_OPEN_NOCREATE; open->op_opentype = (flags & O_CREAT) ? NFS4_OPEN_CREATE : NFS4_OPEN_NOCREATE;
open->op_createmode = NFS4_CREATE_UNCHECKED; open->op_createmode = NFS4_CREATE_UNCHECKED;
...@@ -527,6 +523,10 @@ nfs4_setup_rename(struct nfs4_compound *cp, struct qstr *old, struct qstr *new, ...@@ -527,6 +523,10 @@ nfs4_setup_rename(struct nfs4_compound *cp, struct qstr *old, struct qstr *new,
static void static void
nfs4_setup_renew(struct nfs4_compound *cp) nfs4_setup_renew(struct nfs4_compound *cp)
{ {
struct nfs4_client **client_state = GET_OP(cp, renew);
*client_state = cp->server->nfs4_state;
OPNUM(cp) = OP_RENEW; OPNUM(cp) = OP_RENEW;
cp->req_nops++; cp->req_nops++;
cp->renew_index = cp->req_nops; cp->renew_index = cp->req_nops;
...@@ -575,6 +575,7 @@ nfs4_setup_setclientid(struct nfs4_compound *cp, u32 program, unsigned short por ...@@ -575,6 +575,7 @@ nfs4_setup_setclientid(struct nfs4_compound *cp, u32 program, unsigned short por
sprintf(setclientid->sc_uaddr, "%s.%d.%d", server->ip_addr, port >> 8, port & 255); sprintf(setclientid->sc_uaddr, "%s.%d.%d", server->ip_addr, port >> 8, port & 255);
setclientid->sc_prog = program; setclientid->sc_prog = program;
setclientid->sc_cb_ident = 0; setclientid->sc_cb_ident = 0;
setclientid->sc_state = server->nfs4_state;
OPNUM(cp) = OP_SETCLIENTID; OPNUM(cp) = OP_SETCLIENTID;
cp->req_nops++; cp->req_nops++;
...@@ -583,6 +584,10 @@ nfs4_setup_setclientid(struct nfs4_compound *cp, u32 program, unsigned short por ...@@ -583,6 +584,10 @@ nfs4_setup_setclientid(struct nfs4_compound *cp, u32 program, unsigned short por
static void static void
nfs4_setup_setclientid_confirm(struct nfs4_compound *cp) nfs4_setup_setclientid_confirm(struct nfs4_compound *cp)
{ {
struct nfs4_client **client_state = GET_OP(cp, setclientid_confirm);
*client_state = cp->server->nfs4_state;
OPNUM(cp) = OP_SETCLIENTID_CONFIRM; OPNUM(cp) = OP_SETCLIENTID_CONFIRM;
cp->req_nops++; cp->req_nops++;
cp->renew_index = cp->req_nops; cp->renew_index = cp->req_nops;
......
...@@ -57,8 +57,6 @@ ...@@ -57,8 +57,6 @@
*/ */
#define COOKIE_MAX 0x7fffffff #define COOKIE_MAX 0x7fffffff
#define NFS4_CLIENTID(server) ((server)->nfs4_state->cl_clientid)
#define NFSDBG_FACILITY NFSDBG_XDR #define NFSDBG_FACILITY NFSDBG_XDR
/* Mapping from NFS error code to "errno" error code. */ /* Mapping from NFS error code to "errno" error code. */
...@@ -95,25 +93,22 @@ static struct { ...@@ -95,25 +93,22 @@ static struct {
* task to translate them into Linux-specific versions which are more * task to translate them into Linux-specific versions which are more
* consistent with the style used in NFSv2/v3... * consistent with the style used in NFSv2/v3...
*/ */
#define ENCODE_HEAD \
u32 *p;
#define ENCODE_TAIL \
return 0
#define WRITE32(n) *p++ = htonl(n) #define WRITE32(n) *p++ = htonl(n)
#define WRITE64(n) do { \ #define WRITE64(n) do { \
*p++ = htonl((u32)((n) >> 32)); \ *p++ = htonl((uint32_t)((n) >> 32)); \
*p++ = htonl((u32)(n)); \ *p++ = htonl((uint32_t)(n)); \
} while (0) } while (0)
#define WRITEMEM(ptr,nbytes) do { \ #define WRITEMEM(ptr,nbytes) do { \
p = xdr_writemem(p, ptr, nbytes); \ p = xdr_writemem(p, ptr, nbytes); \
} while (0) } while (0)
#define RESERVE_SPACE(nbytes) do { BUG_ON(cp->p + XDR_QUADLEN(nbytes) > cp->end); p = cp->p; } while (0) #define RESERVE_SPACE(nbytes) do { \
#define ADJUST_ARGS() cp->p = p p = xdr_reserve_space(xdr, nbytes); \
BUG_ON(!p); \
} while (0)
static inline static inline
u32 *xdr_writemem(u32 *p, const void *ptr, int nbytes) uint32_t *xdr_writemem(uint32_t *p, const void *ptr, int nbytes)
{ {
int tmp = XDR_QUADLEN(nbytes); int tmp = XDR_QUADLEN(nbytes);
if (!tmp) if (!tmp)
...@@ -146,18 +141,18 @@ encode_gid(char *p, gid_t gid) ...@@ -146,18 +141,18 @@ encode_gid(char *p, gid_t gid)
} }
static int static int
encode_attrs(struct nfs4_compound *cp, struct iattr *iap) encode_attrs(struct xdr_stream *xdr, struct iattr *iap)
{ {
char owner_name[256]; char owner_name[256];
char owner_group[256]; char owner_group[256];
int owner_namelen = 0; int owner_namelen = 0;
int owner_grouplen = 0; int owner_grouplen = 0;
u32 *q; uint32_t *p;
uint32_t *q;
int len; int len;
u32 bmval0 = 0; uint32_t bmval0 = 0;
u32 bmval1 = 0; uint32_t bmval1 = 0;
int status; int status;
ENCODE_HEAD;
/* /*
* We reserve enough space to write the entire attribute buffer at once. * We reserve enough space to write the entire attribute buffer at once.
...@@ -240,8 +235,6 @@ encode_attrs(struct nfs4_compound *cp, struct iattr *iap) ...@@ -240,8 +235,6 @@ encode_attrs(struct nfs4_compound *cp, struct iattr *iap)
WRITE32(NFS4_SET_TO_SERVER_TIME); WRITE32(NFS4_SET_TO_SERVER_TIME);
} }
ADJUST_ARGS();
/* /*
* Now we backfill the bitmap and the attribute buffer length. * Now we backfill the bitmap and the attribute buffer length.
*/ */
...@@ -256,69 +249,63 @@ encode_attrs(struct nfs4_compound *cp, struct iattr *iap) ...@@ -256,69 +249,63 @@ encode_attrs(struct nfs4_compound *cp, struct iattr *iap)
} }
static int static int
encode_access(struct nfs4_compound *cp, struct nfs4_access *access) encode_access(struct xdr_stream *xdr, struct nfs4_access *access)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(8); RESERVE_SPACE(8);
WRITE32(OP_ACCESS); WRITE32(OP_ACCESS);
WRITE32(access->ac_req_access); WRITE32(access->ac_req_access);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_close(struct nfs4_compound *cp, struct nfs4_close *close) encode_close(struct xdr_stream *xdr, struct nfs4_close *close)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(20); RESERVE_SPACE(20);
WRITE32(OP_CLOSE); WRITE32(OP_CLOSE);
WRITE32(close->cl_seqid); WRITE32(close->cl_seqid);
WRITEMEM(close->cl_stateid, sizeof(nfs4_stateid)); WRITEMEM(close->cl_stateid, sizeof(nfs4_stateid));
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_commit(struct nfs4_compound *cp, struct nfs4_commit *commit) encode_commit(struct xdr_stream *xdr, struct nfs4_commit *commit)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(16); RESERVE_SPACE(16);
WRITE32(OP_COMMIT); WRITE32(OP_COMMIT);
WRITE64(commit->co_start); WRITE64(commit->co_start);
WRITE32(commit->co_len); WRITE32(commit->co_len);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_create(struct nfs4_compound *cp, struct nfs4_create *create) encode_create(struct xdr_stream *xdr, struct nfs4_create *create)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(8); RESERVE_SPACE(8);
WRITE32(OP_CREATE); WRITE32(OP_CREATE);
WRITE32(create->cr_ftype); WRITE32(create->cr_ftype);
ADJUST_ARGS();
switch (create->cr_ftype) { switch (create->cr_ftype) {
case NF4LNK: case NF4LNK:
RESERVE_SPACE(4 + create->cr_textlen); RESERVE_SPACE(4 + create->cr_textlen);
WRITE32(create->cr_textlen); WRITE32(create->cr_textlen);
WRITEMEM(create->cr_text, create->cr_textlen); WRITEMEM(create->cr_text, create->cr_textlen);
ADJUST_ARGS();
break; break;
case NF4BLK: case NF4CHR: case NF4BLK: case NF4CHR:
RESERVE_SPACE(8); RESERVE_SPACE(8);
WRITE32(create->cr_specdata1); WRITE32(create->cr_specdata1);
WRITE32(create->cr_specdata2); WRITE32(create->cr_specdata2);
ADJUST_ARGS();
break; break;
default: default:
...@@ -328,74 +315,69 @@ encode_create(struct nfs4_compound *cp, struct nfs4_create *create) ...@@ -328,74 +315,69 @@ encode_create(struct nfs4_compound *cp, struct nfs4_create *create)
RESERVE_SPACE(4 + create->cr_namelen); RESERVE_SPACE(4 + create->cr_namelen);
WRITE32(create->cr_namelen); WRITE32(create->cr_namelen);
WRITEMEM(create->cr_name, create->cr_namelen); WRITEMEM(create->cr_name, create->cr_namelen);
ADJUST_ARGS();
return encode_attrs(cp, create->cr_attrs); return encode_attrs(xdr, create->cr_attrs);
} }
static int static int
encode_getattr(struct nfs4_compound *cp, struct nfs4_getattr *getattr) encode_getattr(struct xdr_stream *xdr, struct nfs4_getattr *getattr)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(16); RESERVE_SPACE(16);
WRITE32(OP_GETATTR); WRITE32(OP_GETATTR);
WRITE32(2); WRITE32(2);
WRITE32(getattr->gt_bmval[0]); WRITE32(getattr->gt_bmval[0]);
WRITE32(getattr->gt_bmval[1]); WRITE32(getattr->gt_bmval[1]);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_getfh(struct nfs4_compound *cp) encode_getfh(struct xdr_stream *xdr)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(4); RESERVE_SPACE(4);
WRITE32(OP_GETFH); WRITE32(OP_GETFH);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_link(struct nfs4_compound *cp, struct nfs4_link *link) encode_link(struct xdr_stream *xdr, struct nfs4_link *link)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(8 + link->ln_namelen); RESERVE_SPACE(8 + link->ln_namelen);
WRITE32(OP_LINK); WRITE32(OP_LINK);
WRITE32(link->ln_namelen); WRITE32(link->ln_namelen);
WRITEMEM(link->ln_name, link->ln_namelen); WRITEMEM(link->ln_name, link->ln_namelen);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_lookup(struct nfs4_compound *cp, struct nfs4_lookup *lookup) encode_lookup(struct xdr_stream *xdr, struct nfs4_lookup *lookup)
{ {
int len = lookup->lo_name->len; int len = lookup->lo_name->len;
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(8 + len); RESERVE_SPACE(8 + len);
WRITE32(OP_LOOKUP); WRITE32(OP_LOOKUP);
WRITE32(len); WRITE32(len);
WRITEMEM(lookup->lo_name->name, len); WRITEMEM(lookup->lo_name->name, len);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_open(struct nfs4_compound *cp, struct nfs4_open *open) encode_open(struct xdr_stream *xdr, struct nfs4_open *open)
{ {
static int global_id = 0; static int global_id = 0;
int id = global_id++; int id = global_id++;
int status; int status;
ENCODE_HEAD; uint32_t *p;
/* seqid, share_access, share_deny, clientid, ownerlen, owner, opentype */ /* seqid, share_access, share_deny, clientid, ownerlen, owner, opentype */
RESERVE_SPACE(52); RESERVE_SPACE(52);
...@@ -403,24 +385,21 @@ encode_open(struct nfs4_compound *cp, struct nfs4_open *open) ...@@ -403,24 +385,21 @@ encode_open(struct nfs4_compound *cp, struct nfs4_open *open)
WRITE32(0); /* seqid */ WRITE32(0); /* seqid */
WRITE32(open->op_share_access); WRITE32(open->op_share_access);
WRITE32(0); /* for us, share_deny== 0 always */ WRITE32(0); /* for us, share_deny== 0 always */
WRITE64(NFS4_CLIENTID(cp->server)); WRITE64(open->op_client_state->cl_clientid);
WRITE32(4); WRITE32(4);
WRITE32(id); WRITE32(id);
WRITE32(open->op_opentype); WRITE32(open->op_opentype);
ADJUST_ARGS();
if (open->op_opentype == NFS4_OPEN_CREATE) { if (open->op_opentype == NFS4_OPEN_CREATE) {
if (open->op_createmode == NFS4_CREATE_EXCLUSIVE) { if (open->op_createmode == NFS4_CREATE_EXCLUSIVE) {
RESERVE_SPACE(12); RESERVE_SPACE(12);
WRITE32(open->op_createmode); WRITE32(open->op_createmode);
WRITEMEM(open->op_verifier, sizeof(nfs4_verifier)); WRITEMEM(open->op_verifier, sizeof(nfs4_verifier));
ADJUST_ARGS();
} }
else if (open->op_attrs) { else if (open->op_attrs) {
RESERVE_SPACE(4); RESERVE_SPACE(4);
WRITE32(open->op_createmode); WRITE32(open->op_createmode);
ADJUST_ARGS(); if ((status = encode_attrs(xdr, open->op_attrs)))
if ((status = encode_attrs(cp, open->op_attrs)))
return status; return status;
} }
else { else {
...@@ -428,7 +407,6 @@ encode_open(struct nfs4_compound *cp, struct nfs4_open *open) ...@@ -428,7 +407,6 @@ encode_open(struct nfs4_compound *cp, struct nfs4_open *open)
WRITE32(open->op_createmode); WRITE32(open->op_createmode);
WRITE32(0); WRITE32(0);
WRITE32(0); WRITE32(0);
ADJUST_ARGS();
} }
} }
...@@ -436,15 +414,14 @@ encode_open(struct nfs4_compound *cp, struct nfs4_open *open) ...@@ -436,15 +414,14 @@ encode_open(struct nfs4_compound *cp, struct nfs4_open *open)
WRITE32(NFS4_OPEN_CLAIM_NULL); WRITE32(NFS4_OPEN_CLAIM_NULL);
WRITE32(open->op_name->len); WRITE32(open->op_name->len);
WRITEMEM(open->op_name->name, open->op_name->len); WRITEMEM(open->op_name->name, open->op_name->len);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_open_confirm(struct nfs4_compound *cp, struct nfs4_open_confirm *open_confirm) encode_open_confirm(struct xdr_stream *xdr, struct nfs4_open_confirm *open_confirm)
{ {
ENCODE_HEAD; uint32_t *p;
/* /*
* Note: In this "stateless" implementation, the OPEN_CONFIRM * Note: In this "stateless" implementation, the OPEN_CONFIRM
...@@ -454,44 +431,41 @@ encode_open_confirm(struct nfs4_compound *cp, struct nfs4_open_confirm *open_con ...@@ -454,44 +431,41 @@ encode_open_confirm(struct nfs4_compound *cp, struct nfs4_open_confirm *open_con
WRITE32(OP_OPEN_CONFIRM); WRITE32(OP_OPEN_CONFIRM);
WRITEMEM(open_confirm->oc_stateid, sizeof(nfs4_stateid)); WRITEMEM(open_confirm->oc_stateid, sizeof(nfs4_stateid));
WRITE32(1); WRITE32(1);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_putfh(struct nfs4_compound *cp, struct nfs4_putfh *putfh) encode_putfh(struct xdr_stream *xdr, struct nfs4_putfh *putfh)
{ {
int len = putfh->pf_fhandle->size; int len = putfh->pf_fhandle->size;
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(8 + len); RESERVE_SPACE(8 + len);
WRITE32(OP_PUTFH); WRITE32(OP_PUTFH);
WRITE32(len); WRITE32(len);
WRITEMEM(putfh->pf_fhandle->data, len); WRITEMEM(putfh->pf_fhandle->data, len);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_putrootfh(struct nfs4_compound *cp) encode_putrootfh(struct xdr_stream *xdr)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(4); RESERVE_SPACE(4);
WRITE32(OP_PUTROOTFH); WRITE32(OP_PUTROOTFH);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_read(struct nfs4_compound *cp, struct nfs4_read *read, struct rpc_rqst *req) encode_read(struct xdr_stream *xdr, struct nfs4_read *read, struct rpc_rqst *req)
{ {
struct rpc_auth *auth = req->rq_task->tk_auth; struct rpc_auth *auth = req->rq_task->tk_auth;
int replen; int replen;
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(32); RESERVE_SPACE(32);
WRITE32(OP_READ); WRITE32(OP_READ);
...@@ -501,26 +475,24 @@ encode_read(struct nfs4_compound *cp, struct nfs4_read *read, struct rpc_rqst *r ...@@ -501,26 +475,24 @@ encode_read(struct nfs4_compound *cp, struct nfs4_read *read, struct rpc_rqst *r
WRITE32(0); WRITE32(0);
WRITE64(read->rd_offset); WRITE64(read->rd_offset);
WRITE32(read->rd_length); WRITE32(read->rd_length);
ADJUST_ARGS();
/* set up reply iovec /* set up reply iovec
* toplevel status + taglen + rescount + OP_PUTFH + status * toplevel status + taglen + rescount + OP_PUTFH + status
* + OP_READ + status + eof + datalen = 9 * + OP_READ + status + eof + datalen = 9
*/ */
replen = (RPC_REPHDRSIZE + auth->au_rslack + 9 + XDR_QUADLEN(cp->taglen)) << 2; replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2;
req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
xdr_inline_pages(&req->rq_rcv_buf, replen, xdr_inline_pages(&req->rq_rcv_buf, replen,
read->rd_pages, read->rd_pgbase, read->rd_length); read->rd_pages, read->rd_pgbase, read->rd_length);
ENCODE_TAIL; return 0;
} }
static int static int
encode_readdir(struct nfs4_compound *cp, struct nfs4_readdir *readdir, struct rpc_rqst *req) encode_readdir(struct xdr_stream *xdr, struct nfs4_readdir *readdir, struct rpc_rqst *req)
{ {
struct rpc_auth *auth = req->rq_task->tk_auth; struct rpc_auth *auth = req->rq_task->tk_auth;
int replen; int replen;
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(40); RESERVE_SPACE(40);
WRITE32(OP_READDIR); WRITE32(OP_READDIR);
...@@ -531,135 +503,124 @@ encode_readdir(struct nfs4_compound *cp, struct nfs4_readdir *readdir, struct rp ...@@ -531,135 +503,124 @@ encode_readdir(struct nfs4_compound *cp, struct nfs4_readdir *readdir, struct rp
WRITE32(2); WRITE32(2);
WRITE32(readdir->rd_bmval[0]); WRITE32(readdir->rd_bmval[0]);
WRITE32(readdir->rd_bmval[1]); WRITE32(readdir->rd_bmval[1]);
ADJUST_ARGS();
/* set up reply iovec /* set up reply iovec
* toplevel_status + taglen + rescount + OP_PUTFH + status * toplevel_status + taglen + rescount + OP_PUTFH + status
* + OP_READDIR + status + verifer(2) = 9 * + OP_READDIR + status + verifer(2) = 9
*/ */
replen = (RPC_REPHDRSIZE + auth->au_rslack + 9 + XDR_QUADLEN(cp->taglen)) << 2; replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2;
req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->rd_pages, xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->rd_pages,
readdir->rd_pgbase, readdir->rd_count); readdir->rd_pgbase, readdir->rd_count);
ENCODE_TAIL; return 0;
} }
static int static int
encode_readlink(struct nfs4_compound *cp, struct nfs4_readlink *readlink, struct rpc_rqst *req) encode_readlink(struct xdr_stream *xdr, struct nfs4_readlink *readlink, struct rpc_rqst *req)
{ {
struct rpc_auth *auth = req->rq_task->tk_auth; struct rpc_auth *auth = req->rq_task->tk_auth;
int replen; int replen;
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(4); RESERVE_SPACE(4);
WRITE32(OP_READLINK); WRITE32(OP_READLINK);
ADJUST_ARGS();
/* set up reply iovec /* set up reply iovec
* toplevel_status + taglen + rescount + OP_PUTFH + status * toplevel_status + taglen + rescount + OP_PUTFH + status
* + OP_READLINK + status = 7 * + OP_READLINK + status = 7
*/ */
replen = (RPC_REPHDRSIZE + auth->au_rslack + 7 + XDR_QUADLEN(cp->taglen)) << 2; replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
xdr_inline_pages(&req->rq_rcv_buf, replen, readlink->rl_pages, 0, readlink->rl_count); xdr_inline_pages(&req->rq_rcv_buf, replen, readlink->rl_pages, 0, readlink->rl_count);
ENCODE_TAIL; return 0;
} }
static int static int
encode_remove(struct nfs4_compound *cp, struct nfs4_remove *remove) encode_remove(struct xdr_stream *xdr, struct nfs4_remove *remove)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(8 + remove->rm_namelen); RESERVE_SPACE(8 + remove->rm_namelen);
WRITE32(OP_REMOVE); WRITE32(OP_REMOVE);
WRITE32(remove->rm_namelen); WRITE32(remove->rm_namelen);
WRITEMEM(remove->rm_name, remove->rm_namelen); WRITEMEM(remove->rm_name, remove->rm_namelen);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_rename(struct nfs4_compound *cp, struct nfs4_rename *rename) encode_rename(struct xdr_stream *xdr, struct nfs4_rename *rename)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(8 + rename->rn_oldnamelen); RESERVE_SPACE(8 + rename->rn_oldnamelen);
WRITE32(OP_RENAME); WRITE32(OP_RENAME);
WRITE32(rename->rn_oldnamelen); WRITE32(rename->rn_oldnamelen);
WRITEMEM(rename->rn_oldname, rename->rn_oldnamelen); WRITEMEM(rename->rn_oldname, rename->rn_oldnamelen);
ADJUST_ARGS();
RESERVE_SPACE(8 + rename->rn_newnamelen); RESERVE_SPACE(8 + rename->rn_newnamelen);
WRITE32(rename->rn_newnamelen); WRITE32(rename->rn_newnamelen);
WRITEMEM(rename->rn_newname, rename->rn_newnamelen); WRITEMEM(rename->rn_newname, rename->rn_newnamelen);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_renew(struct nfs4_compound *cp) encode_renew(struct xdr_stream *xdr, struct nfs4_client *client_stateid)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(12); RESERVE_SPACE(12);
WRITE32(OP_RENEW); WRITE32(OP_RENEW);
WRITE64(NFS4_CLIENTID(cp->server)); WRITE64(client_stateid->cl_clientid);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_restorefh(struct nfs4_compound *cp) encode_restorefh(struct xdr_stream *xdr)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(4); RESERVE_SPACE(4);
WRITE32(OP_RESTOREFH); WRITE32(OP_RESTOREFH);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_savefh(struct nfs4_compound *cp) encode_savefh(struct xdr_stream *xdr)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(4); RESERVE_SPACE(4);
WRITE32(OP_SAVEFH); WRITE32(OP_SAVEFH);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_setattr(struct nfs4_compound *cp, struct nfs4_setattr *setattr) encode_setattr(struct xdr_stream *xdr, struct nfs4_setattr *setattr)
{ {
int status; int status;
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(20); RESERVE_SPACE(20);
WRITE32(OP_SETATTR); WRITE32(OP_SETATTR);
WRITEMEM(setattr->st_stateid, sizeof(nfs4_stateid)); WRITEMEM(setattr->st_stateid, sizeof(nfs4_stateid));
ADJUST_ARGS();
if ((status = encode_attrs(cp, setattr->st_iap))) if ((status = encode_attrs(xdr, setattr->st_iap)))
return status; return status;
ENCODE_TAIL; return 0;
} }
static int static int
encode_setclientid(struct nfs4_compound *cp, struct nfs4_setclientid *setclientid) encode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid *setclientid)
{ {
u32 total_len; uint32_t total_len;
u32 len1, len2, len3; uint32_t len1, len2, len3;
ENCODE_HEAD; uint32_t *p;
len1 = strlen(setclientid->sc_name); len1 = strlen(setclientid->sc_name);
len2 = strlen(setclientid->sc_netid); len2 = strlen(setclientid->sc_netid);
...@@ -678,30 +639,28 @@ encode_setclientid(struct nfs4_compound *cp, struct nfs4_setclientid *setclienti ...@@ -678,30 +639,28 @@ encode_setclientid(struct nfs4_compound *cp, struct nfs4_setclientid *setclienti
WRITE32(len3); WRITE32(len3);
WRITEMEM(setclientid->sc_uaddr, len3); WRITEMEM(setclientid->sc_uaddr, len3);
WRITE32(setclientid->sc_cb_ident); WRITE32(setclientid->sc_cb_ident);
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_setclientid_confirm(struct nfs4_compound *cp) encode_setclientid_confirm(struct xdr_stream *xdr, struct nfs4_client *client_state)
{ {
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(12 + sizeof(nfs4_verifier)); RESERVE_SPACE(12 + sizeof(nfs4_verifier));
WRITE32(OP_SETCLIENTID_CONFIRM); WRITE32(OP_SETCLIENTID_CONFIRM);
WRITE64(cp->server->nfs4_state->cl_clientid); WRITE64(client_state->cl_clientid);
WRITEMEM(cp->server->nfs4_state->cl_confirm,sizeof(nfs4_verifier)); WRITEMEM(client_state->cl_confirm,sizeof(nfs4_verifier));
ADJUST_ARGS();
ENCODE_TAIL; return 0;
} }
static int static int
encode_write(struct nfs4_compound *cp, struct nfs4_write *write, struct rpc_rqst *req) encode_write(struct xdr_stream *xdr, struct nfs4_write *write, struct rpc_rqst *req)
{ {
struct xdr_buf *sndbuf = &req->rq_snd_buf; struct xdr_buf *sndbuf = &req->rq_snd_buf;
ENCODE_HEAD; uint32_t *p;
RESERVE_SPACE(36); RESERVE_SPACE(36);
WRITE32(OP_WRITE); WRITE32(OP_WRITE);
...@@ -712,20 +671,18 @@ encode_write(struct nfs4_compound *cp, struct nfs4_write *write, struct rpc_rqst ...@@ -712,20 +671,18 @@ encode_write(struct nfs4_compound *cp, struct nfs4_write *write, struct rpc_rqst
WRITE64(write->wr_offset); WRITE64(write->wr_offset);
WRITE32(write->wr_stable_how); WRITE32(write->wr_stable_how);
WRITE32(write->wr_len); WRITE32(write->wr_len);
ADJUST_ARGS();
sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
xdr_encode_pages(sndbuf, write->wr_pages, write->wr_pgbase, write->wr_len); xdr_encode_pages(sndbuf, write->wr_pages, write->wr_pgbase, write->wr_len);
ENCODE_TAIL; return 0;
} }
/* FIXME: this sucks */ /* FIXME: this sucks */
static int static int
encode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqst *req)
{ {
int i, status = 0; int i, status = 0;
ENCODE_HEAD; uint32_t *p;
dprintk("encode_compound: tag=%.*s\n", (int)cp->taglen, cp->tag); dprintk("encode_compound: tag=%.*s\n", (int)cp->taglen, cp->tag);
...@@ -734,81 +691,80 @@ encode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) ...@@ -734,81 +691,80 @@ encode_compound(struct nfs4_compound *cp, struct rpc_rqst *req)
WRITEMEM(cp->tag, cp->taglen); WRITEMEM(cp->tag, cp->taglen);
WRITE32(NFS4_MINOR_VERSION); WRITE32(NFS4_MINOR_VERSION);
WRITE32(cp->req_nops); WRITE32(cp->req_nops);
ADJUST_ARGS();
for (i = 0; i < cp->req_nops; i++) { for (i = 0; i < cp->req_nops; i++) {
switch (cp->ops[i].opnum) { switch (cp->ops[i].opnum) {
case OP_ACCESS: case OP_ACCESS:
status = encode_access(cp, &cp->ops[i].u.access); status = encode_access(xdr, &cp->ops[i].u.access);
break; break;
case OP_CLOSE: case OP_CLOSE:
status = encode_close(cp, &cp->ops[i].u.close); status = encode_close(xdr, &cp->ops[i].u.close);
break; break;
case OP_COMMIT: case OP_COMMIT:
status = encode_commit(cp, &cp->ops[i].u.commit); status = encode_commit(xdr, &cp->ops[i].u.commit);
break; break;
case OP_CREATE: case OP_CREATE:
status = encode_create(cp, &cp->ops[i].u.create); status = encode_create(xdr, &cp->ops[i].u.create);
break; break;
case OP_GETATTR: case OP_GETATTR:
status = encode_getattr(cp, &cp->ops[i].u.getattr); status = encode_getattr(xdr, &cp->ops[i].u.getattr);
break; break;
case OP_GETFH: case OP_GETFH:
status = encode_getfh(cp); status = encode_getfh(xdr);
break; break;
case OP_LINK: case OP_LINK:
status = encode_link(cp, &cp->ops[i].u.link); status = encode_link(xdr, &cp->ops[i].u.link);
break; break;
case OP_LOOKUP: case OP_LOOKUP:
status = encode_lookup(cp, &cp->ops[i].u.lookup); status = encode_lookup(xdr, &cp->ops[i].u.lookup);
break; break;
case OP_OPEN: case OP_OPEN:
status = encode_open(cp, &cp->ops[i].u.open); status = encode_open(xdr, &cp->ops[i].u.open);
break; break;
case OP_OPEN_CONFIRM: case OP_OPEN_CONFIRM:
status = encode_open_confirm(cp, &cp->ops[i].u.open_confirm); status = encode_open_confirm(xdr, &cp->ops[i].u.open_confirm);
break; break;
case OP_PUTFH: case OP_PUTFH:
status = encode_putfh(cp, &cp->ops[i].u.putfh); status = encode_putfh(xdr, &cp->ops[i].u.putfh);
break; break;
case OP_PUTROOTFH: case OP_PUTROOTFH:
status = encode_putrootfh(cp); status = encode_putrootfh(xdr);
break; break;
case OP_READ: case OP_READ:
status = encode_read(cp, &cp->ops[i].u.read, req); status = encode_read(xdr, &cp->ops[i].u.read, req);
break; break;
case OP_READDIR: case OP_READDIR:
status = encode_readdir(cp, &cp->ops[i].u.readdir, req); status = encode_readdir(xdr, &cp->ops[i].u.readdir, req);
break; break;
case OP_READLINK: case OP_READLINK:
status = encode_readlink(cp, &cp->ops[i].u.readlink, req); status = encode_readlink(xdr, &cp->ops[i].u.readlink, req);
break; break;
case OP_REMOVE: case OP_REMOVE:
status = encode_remove(cp, &cp->ops[i].u.remove); status = encode_remove(xdr, &cp->ops[i].u.remove);
break; break;
case OP_RENAME: case OP_RENAME:
status = encode_rename(cp, &cp->ops[i].u.rename); status = encode_rename(xdr, &cp->ops[i].u.rename);
break; break;
case OP_RENEW: case OP_RENEW:
status = encode_renew(cp); status = encode_renew(xdr, cp->ops[i].u.renew);
break; break;
case OP_RESTOREFH: case OP_RESTOREFH:
status = encode_restorefh(cp); status = encode_restorefh(xdr);
break; break;
case OP_SAVEFH: case OP_SAVEFH:
status = encode_savefh(cp); status = encode_savefh(xdr);
break; break;
case OP_SETATTR: case OP_SETATTR:
status = encode_setattr(cp, &cp->ops[i].u.setattr); status = encode_setattr(xdr, &cp->ops[i].u.setattr);
break; break;
case OP_SETCLIENTID: case OP_SETCLIENTID:
status = encode_setclientid(cp, &cp->ops[i].u.setclientid); status = encode_setclientid(xdr, &cp->ops[i].u.setclientid);
break; break;
case OP_SETCLIENTID_CONFIRM: case OP_SETCLIENTID_CONFIRM:
status = encode_setclientid_confirm(cp); status = encode_setclientid_confirm(xdr, cp->ops[i].u.setclientid_confirm);
break; break;
case OP_WRITE: case OP_WRITE:
status = encode_write(cp, &cp->ops[i].u.write, req); status = encode_write(xdr, &cp->ops[i].u.write, req);
break; break;
default: default:
BUG(); BUG();
...@@ -817,7 +773,7 @@ encode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) ...@@ -817,7 +773,7 @@ encode_compound(struct nfs4_compound *cp, struct rpc_rqst *req)
return status; return status;
} }
ENCODE_TAIL; return 0;
} }
/* /*
* END OF "GENERIC" ENCODE ROUTINES. * END OF "GENERIC" ENCODE ROUTINES.
...@@ -828,18 +784,14 @@ encode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) ...@@ -828,18 +784,14 @@ encode_compound(struct nfs4_compound *cp, struct rpc_rqst *req)
* Encode COMPOUND argument * Encode COMPOUND argument
*/ */
static int static int
nfs4_xdr_enc_compound(struct rpc_rqst *req, u32 *p, struct nfs4_compound *cp) nfs4_xdr_enc_compound(struct rpc_rqst *req, uint32_t *p, struct nfs4_compound *cp)
{ {
struct xdr_stream xdr;
int status; int status;
struct xdr_buf *sndbuf = &req->rq_snd_buf;
cp->p = p; xdr_init_encode(&xdr, &req->rq_snd_buf, p);
cp->end = (u32 *) ((char *)req->rq_svec[0].iov_base + req->rq_svec[0].iov_len); status = encode_compound(&xdr, cp, req);
status = encode_compound(cp, req);
cp->timestamp = jiffies; cp->timestamp = jiffies;
if (!status && !sndbuf->page_len)
req->rq_slen = xdr_adjust_iovec(sndbuf->head, cp->p);
return status; return status;
} }
...@@ -854,9 +806,6 @@ nfs4_xdr_enc_compound(struct rpc_rqst *req, u32 *p, struct nfs4_compound *cp) ...@@ -854,9 +806,6 @@ nfs4_xdr_enc_compound(struct rpc_rqst *req, u32 *p, struct nfs4_compound *cp)
* task to translate them into Linux-specific versions which are more * task to translate them into Linux-specific versions which are more
* consistent with the style used in NFSv2/v3... * consistent with the style used in NFSv2/v3...
*/ */
#define DECODE_HEAD \
u32 *p; \
int status
#define DECODE_TAIL \ #define DECODE_TAIL \
status = 0; \ status = 0; \
out: \ out: \
...@@ -881,11 +830,13 @@ xdr_error: \ ...@@ -881,11 +830,13 @@ xdr_error: \
p += XDR_QUADLEN(nbytes); \ p += XDR_QUADLEN(nbytes); \
} while (0) } while (0)
#define READ_BUF(nbytes) do { \ #define READ_BUF(nbytes) do { \
if (nbytes > (u32)((char *)cp->end - (char *)cp->p)) \ p = xdr_inline_decode(xdr, nbytes); \
goto xdr_error; \ if (!p) { \
p = cp->p; \ printk(KERN_WARNING "%s: reply buffer overflowed in line %d.", \
cp->p += XDR_QUADLEN(nbytes); \ __FUNCTION__, __LINE__); \
return -EIO; \
} \
} while (0) } while (0)
/* /*
...@@ -893,7 +844,7 @@ xdr_error: \ ...@@ -893,7 +844,7 @@ xdr_error: \
* upcall gets in... * upcall gets in...
*/ */
static int static int
decode_uid(char *p, u32 len, uid_t *uid) decode_uid(char *p, uint32_t len, uid_t *uid)
{ {
*uid = -2; *uid = -2;
return 0; return 0;
...@@ -904,82 +855,78 @@ decode_uid(char *p, u32 len, uid_t *uid) ...@@ -904,82 +855,78 @@ decode_uid(char *p, u32 len, uid_t *uid)
* upcall gets in... * upcall gets in...
*/ */
static int static int
decode_gid(char *p, u32 len, gid_t *gid) decode_gid(char *p, uint32_t len, gid_t *gid)
{ {
*gid = -2; *gid = -2;
return 0; return 0;
} }
static int static int
decode_change_info(struct nfs4_compound *cp, struct nfs4_change_info *cinfo) decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
{ {
DECODE_HEAD; uint32_t *p;
READ_BUF(20); READ_BUF(20);
READ32(cinfo->atomic); READ32(cinfo->atomic);
READ64(cinfo->before); READ64(cinfo->before);
READ64(cinfo->after); READ64(cinfo->after);
return 0;
DECODE_TAIL;
} }
static int static int
decode_access(struct nfs4_compound *cp, int nfserr, struct nfs4_access *access) decode_access(struct xdr_stream *xdr, int nfserr, struct nfs4_access *access)
{ {
u32 supp, acc; uint32_t *p;
DECODE_HEAD; uint32_t supp, acc;
if (!nfserr) { if (!nfserr) {
READ_BUF(8); READ_BUF(8);
READ32(supp); READ32(supp);
READ32(acc); READ32(acc);
status = -EIO;
if ((supp & ~access->ac_req_access) || (acc & ~supp)) { if ((supp & ~access->ac_req_access) || (acc & ~supp)) {
printk(KERN_NOTICE "NFS: server returned bad bits in access call!\n"); printk(KERN_NOTICE "NFS: server returned bad bits in access call!\n");
goto out; return -EIO;
} }
*access->ac_resp_supported = supp; *access->ac_resp_supported = supp;
*access->ac_resp_access = acc; *access->ac_resp_access = acc;
} }
return 0;
DECODE_TAIL;
} }
static int static int
decode_close(struct nfs4_compound *cp, int nfserr, struct nfs4_close *close) decode_close(struct xdr_stream *xdr, int nfserr, struct nfs4_close *close)
{ {
DECODE_HEAD; uint32_t *p;
if (!nfserr) { if (!nfserr) {
READ_BUF(sizeof(nfs4_stateid)); READ_BUF(sizeof(nfs4_stateid));
COPYMEM(close->cl_stateid, sizeof(nfs4_stateid)); COPYMEM(close->cl_stateid, sizeof(nfs4_stateid));
} }
return 0;
DECODE_TAIL;
} }
static int static int
decode_commit(struct nfs4_compound *cp, int nfserr, struct nfs4_commit *commit) decode_commit(struct xdr_stream *xdr, int nfserr, struct nfs4_commit *commit)
{ {
DECODE_HEAD; uint32_t *p;
if (!nfserr) { if (!nfserr) {
READ_BUF(8); READ_BUF(8);
COPYMEM(commit->co_verifier->verifier, 8); COPYMEM(commit->co_verifier->verifier, 8);
} }
return 0;
DECODE_TAIL;
} }
static int static int
decode_create(struct nfs4_compound *cp, int nfserr, struct nfs4_create *create) decode_create(struct xdr_stream *xdr, int nfserr, struct nfs4_create *create)
{ {
u32 bmlen; uint32_t *p;
DECODE_HEAD; uint32_t bmlen;
int status;
if (!nfserr) { if (!nfserr) {
if ((status = decode_change_info(cp, create->cr_cinfo))) if ((status = decode_change_info(xdr, create->cr_cinfo)))
goto out; goto out;
READ_BUF(4); READ_BUF(4);
READ32(bmlen); READ32(bmlen);
...@@ -991,27 +938,28 @@ decode_create(struct nfs4_compound *cp, int nfserr, struct nfs4_create *create) ...@@ -991,27 +938,28 @@ decode_create(struct nfs4_compound *cp, int nfserr, struct nfs4_create *create)
DECODE_TAIL; DECODE_TAIL;
} }
extern u32 nfs4_fattr_bitmap[2]; extern uint32_t nfs4_fattr_bitmap[2];
extern u32 nfs4_fsinfo_bitmap[2]; extern uint32_t nfs4_fsinfo_bitmap[2];
extern u32 nfs4_fsstat_bitmap[2]; extern uint32_t nfs4_fsstat_bitmap[2];
extern u32 nfs4_pathconf_bitmap[2]; extern uint32_t nfs4_pathconf_bitmap[2];
static int static int
decode_getattr(struct nfs4_compound *cp, int nfserr, struct nfs4_getattr *getattr) decode_getattr(struct xdr_stream *xdr, int nfserr, struct nfs4_getattr *getattr)
{ {
struct nfs_fattr *nfp = getattr->gt_attrs; struct nfs_fattr *nfp = getattr->gt_attrs;
struct nfs_fsstat *fsstat = getattr->gt_fsstat; struct nfs_fsstat *fsstat = getattr->gt_fsstat;
struct nfs_fsinfo *fsinfo = getattr->gt_fsinfo; struct nfs_fsinfo *fsinfo = getattr->gt_fsinfo;
struct nfs_pathconf *pathconf = getattr->gt_pathconf; struct nfs_pathconf *pathconf = getattr->gt_pathconf;
u32 bmlen; uint32_t *p;
u32 bmval0 = 0; uint32_t bmlen;
u32 bmval1 = 0; uint32_t bmval0 = 0;
u32 attrlen; uint32_t bmval1 = 0;
u32 dummy32; uint32_t attrlen;
u32 len = 0; uint32_t dummy32;
uint32_t len = 0;
unsigned int type; unsigned int type;
int fmode = 0; int fmode = 0;
DECODE_HEAD; int status;
if (nfserr) if (nfserr)
goto success; goto success;
...@@ -1060,7 +1008,7 @@ decode_getattr(struct nfs4_compound *cp, int nfserr, struct nfs4_getattr *getatt ...@@ -1060,7 +1008,7 @@ decode_getattr(struct nfs4_compound *cp, int nfserr, struct nfs4_getattr *getatt
} }
nfp->type = nfs_type2fmt[type].nfs2type; nfp->type = nfs_type2fmt[type].nfs2type;
fmode = nfs_type2fmt[type].mode; fmode = nfs_type2fmt[type].mode;
dprintk("read_attrs: type=%d\n", (u32)nfp->type); dprintk("read_attrs: type=%d\n", (uint32_t)nfp->type);
} }
if (bmval0 & FATTR4_WORD0_CHANGE) { if (bmval0 & FATTR4_WORD0_CHANGE) {
READ_BUF(8); READ_BUF(8);
...@@ -1250,11 +1198,12 @@ decode_getattr(struct nfs4_compound *cp, int nfserr, struct nfs4_getattr *getatt ...@@ -1250,11 +1198,12 @@ decode_getattr(struct nfs4_compound *cp, int nfserr, struct nfs4_getattr *getatt
} }
static int static int
decode_getfh(struct nfs4_compound *cp, int nfserr, struct nfs4_getfh *getfh) decode_getfh(struct xdr_stream *xdr, int nfserr, struct nfs4_getfh *getfh)
{ {
struct nfs_fh *fh = getfh->gf_fhandle; struct nfs_fh *fh = getfh->gf_fhandle;
int len; uint32_t *p;
DECODE_HEAD; uint32_t len;
int status;
/* Zero handle first to allow comparisons */ /* Zero handle first to allow comparisons */
memset(fh, 0, sizeof(*fh)); memset(fh, 0, sizeof(*fh));
...@@ -1273,26 +1222,27 @@ decode_getfh(struct nfs4_compound *cp, int nfserr, struct nfs4_getfh *getfh) ...@@ -1273,26 +1222,27 @@ decode_getfh(struct nfs4_compound *cp, int nfserr, struct nfs4_getfh *getfh)
} }
static int static int
decode_link(struct nfs4_compound *cp, int nfserr, struct nfs4_link *link) decode_link(struct xdr_stream *xdr, int nfserr, struct nfs4_link *link)
{ {
int status = 0; int status = 0;
if (!nfserr) if (!nfserr)
status = decode_change_info(cp, link->ln_cinfo); status = decode_change_info(xdr, link->ln_cinfo);
return status; return status;
} }
static int static int
decode_open(struct nfs4_compound *cp, int nfserr, struct nfs4_open *open) decode_open(struct xdr_stream *xdr, int nfserr, struct nfs4_open *open)
{ {
u32 bmlen, delegation_type; uint32_t *p;
DECODE_HEAD; uint32_t bmlen, delegation_type;
int status;
if (!nfserr) { if (!nfserr) {
READ_BUF(sizeof(nfs4_stateid)); READ_BUF(sizeof(nfs4_stateid));
COPYMEM(open->op_stateid, sizeof(nfs4_stateid)); COPYMEM(open->op_stateid, sizeof(nfs4_stateid));
decode_change_info(cp, open->op_cinfo); decode_change_info(xdr, open->op_cinfo);
READ_BUF(8); READ_BUF(8);
READ32(*open->op_rflags); READ32(*open->op_rflags);
...@@ -1311,23 +1261,23 @@ decode_open(struct nfs4_compound *cp, int nfserr, struct nfs4_open *open) ...@@ -1311,23 +1261,23 @@ decode_open(struct nfs4_compound *cp, int nfserr, struct nfs4_open *open)
} }
static int static int
decode_open_confirm(struct nfs4_compound *cp, int nfserr, struct nfs4_open_confirm *open_confirm) decode_open_confirm(struct xdr_stream *xdr, int nfserr, struct nfs4_open_confirm *open_confirm)
{ {
DECODE_HEAD; uint32_t *p;
if (!nfserr) { if (!nfserr) {
READ_BUF(sizeof(nfs4_stateid)); READ_BUF(sizeof(nfs4_stateid));
COPYMEM(open_confirm->oc_stateid, sizeof(nfs4_stateid)); COPYMEM(open_confirm->oc_stateid, sizeof(nfs4_stateid));
} }
return 0;
DECODE_TAIL;
} }
static int static int
decode_read(struct nfs4_compound *cp, int nfserr, struct nfs4_read *read) decode_read(struct xdr_stream *xdr, int nfserr, struct nfs4_read *read)
{ {
u32 throwaway; uint32_t throwaway;
DECODE_HEAD; uint32_t *p;
int status;
if (!nfserr) { if (!nfserr) {
READ_BUF(8); READ_BUF(8);
...@@ -1344,23 +1294,22 @@ decode_read(struct nfs4_compound *cp, int nfserr, struct nfs4_read *read) ...@@ -1344,23 +1294,22 @@ decode_read(struct nfs4_compound *cp, int nfserr, struct nfs4_read *read)
} }
static int static int
decode_readdir(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, struct nfs4_readdir *readdir) decode_readdir(struct xdr_stream *xdr, int nfserr, struct rpc_rqst *req, struct nfs4_readdir *readdir)
{ {
struct xdr_buf *rcvbuf = &req->rq_rcv_buf; struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
struct page *page = *rcvbuf->pages; struct page *page = *rcvbuf->pages;
unsigned int pglen = rcvbuf->page_len; unsigned int pglen = rcvbuf->page_len;
u32 *end, *entry; uint32_t *end, *entry, *p;
u32 len, attrlen, word; uint32_t len, attrlen, word;
int i; int i;
DECODE_HEAD;
if (!nfserr) { if (!nfserr) {
READ_BUF(8); READ_BUF(8);
COPYMEM(readdir->rd_resp_verifier, 8); COPYMEM(readdir->rd_resp_verifier, 8);
BUG_ON(pglen > PAGE_CACHE_SIZE); BUG_ON(pglen > PAGE_CACHE_SIZE);
p = (u32 *) kmap(page); p = (uint32_t *) kmap(page);
end = (u32 *) ((char *)p + pglen + readdir->rd_pgbase); end = (uint32_t *) ((char *)p + pglen + readdir->rd_pgbase);
while (*p++) { while (*p++) {
entry = p - 1; entry = p - 1;
...@@ -1406,7 +1355,7 @@ decode_readdir(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, struc ...@@ -1406,7 +1355,7 @@ decode_readdir(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, struc
kunmap(page); kunmap(page);
} }
DECODE_TAIL; return 0;
short_pkt: short_pkt:
printk(KERN_NOTICE "NFS: short packet in readdir reply!\n"); printk(KERN_NOTICE "NFS: short packet in readdir reply!\n");
/* truncate listing */ /* truncate listing */
...@@ -1419,11 +1368,11 @@ decode_readdir(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, struc ...@@ -1419,11 +1368,11 @@ decode_readdir(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, struc
} }
static int static int
decode_readlink(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, struct nfs4_readlink *readlink) decode_readlink(struct xdr_stream *xdr, int nfserr, struct rpc_rqst *req, struct nfs4_readlink *readlink)
{ {
struct xdr_buf *rcvbuf = &req->rq_rcv_buf; struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
u32 *strlen; uint32_t *strlen;
u32 len; uint32_t len;
char *string; char *string;
if (!nfserr) { if (!nfserr) {
...@@ -1434,7 +1383,7 @@ decode_readlink(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, stru ...@@ -1434,7 +1383,7 @@ decode_readlink(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, stru
* and and null-terminate the text (the VFS expects * and and null-terminate the text (the VFS expects
* null-termination). * null-termination).
*/ */
strlen = (u32 *) kmap(rcvbuf->pages[0]); strlen = (uint32_t *) kmap(rcvbuf->pages[0]);
len = ntohl(*strlen); len = ntohl(*strlen);
if (len > PAGE_CACHE_SIZE - 5) { if (len > PAGE_CACHE_SIZE - 5) {
printk(KERN_WARNING "nfs: server returned giant symlink!\n"); printk(KERN_WARNING "nfs: server returned giant symlink!\n");
...@@ -1451,25 +1400,25 @@ decode_readlink(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, stru ...@@ -1451,25 +1400,25 @@ decode_readlink(struct nfs4_compound *cp, int nfserr, struct rpc_rqst *req, stru
} }
static int static int
decode_remove(struct nfs4_compound *cp, int nfserr, struct nfs4_remove *remove) decode_remove(struct xdr_stream *xdr, int nfserr, struct nfs4_remove *remove)
{ {
int status; int status;
status = 0; status = 0;
if (!nfserr) if (!nfserr)
status = decode_change_info(cp, remove->rm_cinfo); status = decode_change_info(xdr, remove->rm_cinfo);
return status; return status;
} }
static int static int
decode_rename(struct nfs4_compound *cp, int nfserr, struct nfs4_rename *rename) decode_rename(struct xdr_stream *xdr, int nfserr, struct nfs4_rename *rename)
{ {
int status = 0; int status = 0;
if (!nfserr) { if (!nfserr) {
if ((status = decode_change_info(cp, rename->rn_src_cinfo))) if ((status = decode_change_info(xdr, rename->rn_src_cinfo)))
goto out; goto out;
if ((status = decode_change_info(cp, rename->rn_dst_cinfo))) if ((status = decode_change_info(xdr, rename->rn_dst_cinfo)))
goto out; goto out;
} }
out: out:
...@@ -1477,10 +1426,11 @@ decode_rename(struct nfs4_compound *cp, int nfserr, struct nfs4_rename *rename) ...@@ -1477,10 +1426,11 @@ decode_rename(struct nfs4_compound *cp, int nfserr, struct nfs4_rename *rename)
} }
static int static int
decode_setattr(struct nfs4_compound *cp) decode_setattr(struct xdr_stream *xdr)
{ {
u32 bmlen; uint32_t *p;
DECODE_HEAD; uint32_t bmlen;
int status;
READ_BUF(4); READ_BUF(4);
READ32(bmlen); READ32(bmlen);
...@@ -1492,17 +1442,17 @@ decode_setattr(struct nfs4_compound *cp) ...@@ -1492,17 +1442,17 @@ decode_setattr(struct nfs4_compound *cp)
} }
static int static int
decode_setclientid(struct nfs4_compound *cp, int nfserr) decode_setclientid(struct xdr_stream *xdr, int nfserr, struct nfs4_setclientid *setclientid)
{ {
DECODE_HEAD; uint32_t *p;
if (!nfserr) { if (!nfserr) {
READ_BUF(8 + sizeof(nfs4_verifier)); READ_BUF(8 + sizeof(nfs4_verifier));
READ64(cp->server->nfs4_state->cl_clientid); READ64(setclientid->sc_state->cl_clientid);
COPYMEM(cp->server->nfs4_state->cl_confirm, sizeof(nfs4_verifier)); COPYMEM(setclientid->sc_state->cl_confirm, sizeof(nfs4_verifier));
} }
else if (nfserr == NFSERR_CLID_INUSE) { else if (nfserr == NFSERR_CLID_INUSE) {
u32 len; uint32_t len;
/* skip netid string */ /* skip netid string */
READ_BUF(4); READ_BUF(4);
...@@ -1515,13 +1465,14 @@ decode_setclientid(struct nfs4_compound *cp, int nfserr) ...@@ -1515,13 +1465,14 @@ decode_setclientid(struct nfs4_compound *cp, int nfserr)
READ_BUF(len); READ_BUF(len);
} }
DECODE_TAIL; return 0;
} }
static int static int
decode_write(struct nfs4_compound *cp, int nfserr, struct nfs4_write *write) decode_write(struct xdr_stream *xdr, int nfserr, struct nfs4_write *write)
{ {
DECODE_HEAD; uint32_t *p;
int status;
if (!nfserr) { if (!nfserr) {
READ_BUF(16); READ_BUF(16);
...@@ -1537,11 +1488,12 @@ decode_write(struct nfs4_compound *cp, int nfserr, struct nfs4_write *write) ...@@ -1537,11 +1488,12 @@ decode_write(struct nfs4_compound *cp, int nfserr, struct nfs4_write *write)
/* FIXME: this sucks */ /* FIXME: this sucks */
static int static int
decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqst *req)
{ {
u32 taglen; uint32_t *p;
u32 opnum, nfserr; uint32_t taglen;
DECODE_HEAD; uint32_t opnum, nfserr;
int status;
READ_BUF(8); READ_BUF(8);
READ32(cp->toplevel_status); READ32(cp->toplevel_status);
...@@ -1584,34 +1536,34 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) ...@@ -1584,34 +1536,34 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req)
switch (opnum) { switch (opnum) {
case OP_ACCESS: case OP_ACCESS:
status = decode_access(cp, nfserr, &cp->ops[cp->nops].u.access); status = decode_access(xdr, nfserr, &cp->ops[cp->nops].u.access);
break; break;
case OP_CLOSE: case OP_CLOSE:
status = decode_close(cp, nfserr, &cp->ops[cp->nops].u.close); status = decode_close(xdr, nfserr, &cp->ops[cp->nops].u.close);
break; break;
case OP_COMMIT: case OP_COMMIT:
status = decode_commit(cp, nfserr, &cp->ops[cp->nops].u.commit); status = decode_commit(xdr, nfserr, &cp->ops[cp->nops].u.commit);
break; break;
case OP_CREATE: case OP_CREATE:
status = decode_create(cp, nfserr, &cp->ops[cp->nops].u.create); status = decode_create(xdr, nfserr, &cp->ops[cp->nops].u.create);
break; break;
case OP_GETATTR: case OP_GETATTR:
status = decode_getattr(cp, nfserr, &cp->ops[cp->nops].u.getattr); status = decode_getattr(xdr, nfserr, &cp->ops[cp->nops].u.getattr);
break; break;
case OP_GETFH: case OP_GETFH:
status = decode_getfh(cp, nfserr, &cp->ops[cp->nops].u.getfh); status = decode_getfh(xdr, nfserr, &cp->ops[cp->nops].u.getfh);
break; break;
case OP_LINK: case OP_LINK:
status = decode_link(cp, nfserr, &cp->ops[cp->nops].u.link); status = decode_link(xdr, nfserr, &cp->ops[cp->nops].u.link);
break; break;
case OP_LOOKUP: case OP_LOOKUP:
status = 0; status = 0;
break; break;
case OP_OPEN: case OP_OPEN:
status = decode_open(cp, nfserr, &cp->ops[cp->nops].u.open); status = decode_open(xdr, nfserr, &cp->ops[cp->nops].u.open);
break; break;
case OP_OPEN_CONFIRM: case OP_OPEN_CONFIRM:
status = decode_open_confirm(cp, nfserr, &cp->ops[cp->nops].u.open_confirm); status = decode_open_confirm(xdr, nfserr, &cp->ops[cp->nops].u.open_confirm);
break; break;
case OP_PUTFH: case OP_PUTFH:
status = 0; status = 0;
...@@ -1620,22 +1572,22 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) ...@@ -1620,22 +1572,22 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req)
status = 0; status = 0;
break; break;
case OP_READ: case OP_READ:
status = decode_read(cp, nfserr, &cp->ops[cp->nops].u.read); status = decode_read(xdr, nfserr, &cp->ops[cp->nops].u.read);
break; break;
case OP_READDIR: case OP_READDIR:
status = decode_readdir(cp, nfserr, req, &cp->ops[cp->nops].u.readdir); status = decode_readdir(xdr, nfserr, req, &cp->ops[cp->nops].u.readdir);
break; break;
case OP_READLINK: case OP_READLINK:
status = decode_readlink(cp, nfserr, req, &cp->ops[cp->nops].u.readlink); status = decode_readlink(xdr, nfserr, req, &cp->ops[cp->nops].u.readlink);
break; break;
case OP_RESTOREFH: case OP_RESTOREFH:
status = 0; status = 0;
break; break;
case OP_REMOVE: case OP_REMOVE:
status = decode_remove(cp, nfserr, &cp->ops[cp->nops].u.remove); status = decode_remove(xdr, nfserr, &cp->ops[cp->nops].u.remove);
break; break;
case OP_RENAME: case OP_RENAME:
status = decode_rename(cp, nfserr, &cp->ops[cp->nops].u.rename); status = decode_rename(xdr, nfserr, &cp->ops[cp->nops].u.rename);
break; break;
case OP_RENEW: case OP_RENEW:
status = 0; status = 0;
...@@ -1644,16 +1596,16 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) ...@@ -1644,16 +1596,16 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req)
status = 0; status = 0;
break; break;
case OP_SETATTR: case OP_SETATTR:
status = decode_setattr(cp); status = decode_setattr(xdr);
break; break;
case OP_SETCLIENTID: case OP_SETCLIENTID:
status = decode_setclientid(cp, nfserr); status = decode_setclientid(xdr, nfserr, &cp->ops[cp->nops].u.setclientid);
break; break;
case OP_SETCLIENTID_CONFIRM: case OP_SETCLIENTID_CONFIRM:
status = 0; status = 0;
break; break;
case OP_WRITE: case OP_WRITE:
status = decode_write(cp, nfserr, &cp->ops[cp->nops].u.write); status = decode_write(xdr, nfserr, &cp->ops[cp->nops].u.write);
break; break;
default: default:
BUG(); BUG();
...@@ -1673,14 +1625,13 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req) ...@@ -1673,14 +1625,13 @@ decode_compound(struct nfs4_compound *cp, struct rpc_rqst *req)
* Decode COMPOUND response * Decode COMPOUND response
*/ */
static int static int
nfs4_xdr_dec_compound(struct rpc_rqst *rqstp, u32 *p, struct nfs4_compound *cp) nfs4_xdr_dec_compound(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_compound *cp)
{ {
struct xdr_stream xdr;
int status; int status;
cp->p = p; xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
cp->end = (u32 *) ((u8 *) rqstp->rq_rvec->iov_base + rqstp->rq_rvec->iov_len); if ((status = decode_compound(&xdr, cp, rqstp)))
if ((status = decode_compound(cp, rqstp)))
goto out; goto out;
status = 0; status = 0;
...@@ -1691,10 +1642,10 @@ nfs4_xdr_dec_compound(struct rpc_rqst *rqstp, u32 *p, struct nfs4_compound *cp) ...@@ -1691,10 +1642,10 @@ nfs4_xdr_dec_compound(struct rpc_rqst *rqstp, u32 *p, struct nfs4_compound *cp)
return status; return status;
} }
u32 * uint32_t *
nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus) nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
{ {
u32 len; uint32_t len;
if (!*p++) { if (!*p++) {
if (!*p) if (!*p)
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
* *
* *
* $Id: cpufreq.h,v 1.27 2002/10/08 14:54:23 db Exp $ * $Id: cpufreq.h,v 1.29 2002/11/11 15:35:47 db Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -104,7 +104,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu ...@@ -104,7 +104,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu
* CPUFREQ DRIVER INTERFACE * * CPUFREQ DRIVER INTERFACE *
*********************************************************************/ *********************************************************************/
typedef void (*cpufreq_policy_t) (struct cpufreq_policy *policy); typedef int (*cpufreq_policy_t) (struct cpufreq_policy *policy);
struct cpufreq_driver { struct cpufreq_driver {
/* needed by all drivers */ /* needed by all drivers */
...@@ -116,7 +116,7 @@ struct cpufreq_driver { ...@@ -116,7 +116,7 @@ struct cpufreq_driver {
#endif #endif
/* 2.4. compatible API */ /* 2.4. compatible API */
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
unsigned int cpu_min_freq; unsigned int cpu_min_freq[NR_CPUS];
unsigned int cpu_cur_freq[NR_CPUS]; unsigned int cpu_cur_freq[NR_CPUS];
#endif #endif
}; };
...@@ -205,19 +205,19 @@ enum { ...@@ -205,19 +205,19 @@ enum {
CPU_NR_FREQ = 3, CPU_NR_FREQ = 3,
}; };
#define CTL_CPU_VARS_SPEED_MAX { \ #define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
.ctl_name = CPU_NR_FREQ_MAX, \ .ctl_name = CPU_NR_FREQ_MAX, \
.data = &cpu_max_freq, \ .data = &cpu_max_freq[cpunr], \
.procname = "speed-max", \ .procname = "speed-max", \
.maxlen = sizeof(cpu_max_freq),\ .maxlen = sizeof(cpu_max_freq[cpunr]),\
.mode = 0444, \ .mode = 0444, \
.proc_handler = proc_dointvec, } .proc_handler = proc_dointvec, }
#define CTL_CPU_VARS_SPEED_MIN { \ #define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
.ctl_name = CPU_NR_FREQ_MIN, \ .ctl_name = CPU_NR_FREQ_MIN, \
.data = &cpu_min_freq, \ .data = &cpu_min_freq[cpunr], \
.procname = "speed-min", \ .procname = "speed-min", \
.maxlen = sizeof(cpu_min_freq),\ .maxlen = sizeof(cpu_min_freq[cpunr]),\
.mode = 0444, \ .mode = 0444, \
.proc_handler = proc_dointvec, } .proc_handler = proc_dointvec, }
...@@ -230,8 +230,8 @@ enum { ...@@ -230,8 +230,8 @@ enum {
.extra1 = (void*) (cpunr), } .extra1 = (void*) (cpunr), }
#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\ #define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
CTL_CPU_VARS_SPEED_MAX, \ CTL_CPU_VARS_SPEED_MAX(cpunr), \
CTL_CPU_VARS_SPEED_MIN, \ CTL_CPU_VARS_SPEED_MIN(cpunr), \
CTL_CPU_VARS_SPEED(cpunr), \ CTL_CPU_VARS_SPEED(cpunr), \
{ .ctl_name = 0, }, } { .ctl_name = 0, }, }
......
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
#define _LINUX_INTERRUPT_H #define _LINUX_INTERRUPT_H
#include <linux/config.h> #include <linux/config.h>
#include <linux/linkage.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/hardirq.h> #include <asm/hardirq.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/softirq.h> #include <asm/softirq.h>
#include <asm/system.h>
struct irqaction { struct irqaction {
void (*handler)(int, void *, struct pt_regs *); void (*handler)(int, void *, struct pt_regs *);
......
/* /*
* Motion Eye video4linux driver for Sony Vaio PictureBook * Motion Eye video4linux driver for Sony Vaio PictureBook
* *
* Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcve * Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
*
* Copyright (C) 2001-2002 Alcve <www.alcove.com>
* *
* Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
* *
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#if defined(__KERNEL__) && defined(CONFIG_NETFILTER)
#include <asm/atomic.h> #include <asm/atomic.h>
#endif
/* Bridge Hooks */ /* Bridge Hooks */
/* After promisc drops, checksum checks. */ /* After promisc drops, checksum checks. */
...@@ -23,6 +25,8 @@ ...@@ -23,6 +25,8 @@
#define NF_BR_BROUTING 5 #define NF_BR_BROUTING 5
#define NF_BR_NUMHOOKS 6 #define NF_BR_NUMHOOKS 6
#ifdef __KERNEL__
#define BRNF_PKT_TYPE 0x01 #define BRNF_PKT_TYPE 0x01
#define BRNF_BRIDGED_DNAT 0x02 #define BRNF_BRIDGED_DNAT 0x02
#define BRNF_DONT_TAKE_PARENT 0x04 #define BRNF_DONT_TAKE_PARENT 0x04
...@@ -38,6 +42,7 @@ enum nf_br_hook_priorities { ...@@ -38,6 +42,7 @@ enum nf_br_hook_priorities {
NF_BR_PRI_LAST = INT_MAX, NF_BR_PRI_LAST = INT_MAX,
}; };
#ifdef CONFIG_NETFILTER
static inline static inline
struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
{ {
...@@ -57,5 +62,7 @@ struct bridge_skb_cb { ...@@ -57,5 +62,7 @@ struct bridge_skb_cb {
__u32 ipv4; __u32 ipv4;
} daddr; } daddr;
}; };
#endif /* CONFIG_NETFILTER */
#endif /* __KERNEL__ */
#endif #endif
...@@ -398,6 +398,7 @@ struct nfs4_lookup { ...@@ -398,6 +398,7 @@ struct nfs4_lookup {
}; };
struct nfs4_open { struct nfs4_open {
struct nfs4_client * op_client_state; /* request */
u32 op_share_access; /* request */ u32 op_share_access; /* request */
u32 op_opentype; /* request */ u32 op_opentype; /* request */
u32 op_createmode; /* request */ u32 op_createmode; /* request */
...@@ -472,6 +473,7 @@ struct nfs4_setclientid { ...@@ -472,6 +473,7 @@ struct nfs4_setclientid {
char sc_netid[4]; /* request */ char sc_netid[4]; /* request */
char sc_uaddr[24]; /* request */ char sc_uaddr[24]; /* request */
u32 sc_cb_ident; /* request */ u32 sc_cb_ident; /* request */
struct nfs4_client * sc_state; /* response */
}; };
struct nfs4_write { struct nfs4_write {
...@@ -504,8 +506,10 @@ struct nfs4_op { ...@@ -504,8 +506,10 @@ struct nfs4_op {
struct nfs4_readlink readlink; struct nfs4_readlink readlink;
struct nfs4_remove remove; struct nfs4_remove remove;
struct nfs4_rename rename; struct nfs4_rename rename;
struct nfs4_client * renew;
struct nfs4_setattr setattr; struct nfs4_setattr setattr;
struct nfs4_setclientid setclientid; struct nfs4_setclientid setclientid;
struct nfs4_client * setclientid_confirm;
struct nfs4_write write; struct nfs4_write write;
} u; } u;
}; };
......
...@@ -601,8 +601,8 @@ int pci_enable_wake(struct pci_dev *dev, u32 state, int enable); ...@@ -601,8 +601,8 @@ int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
void pbus_assign_resources(struct pci_bus *bus); void pci_bus_assign_resources(struct pci_bus *bus);
void pbus_size_bridges(struct pci_bus *bus); void pci_bus_size_bridges(struct pci_bus *bus);
int pci_claim_resource(struct pci_dev *, int); int pci_claim_resource(struct pci_dev *, int);
void pci_assign_unassigned_resources(void); void pci_assign_unassigned_resources(void);
void pdev_enable_device(struct pci_dev *); void pdev_enable_device(struct pci_dev *);
......
/* /*
* Sony Programmable I/O Control Device driver for VAIO * Sony Programmable I/O Control Device driver for VAIO
* *
* Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcve * Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
*
* Copyright (C) 2001-2002 Alcve <www.alcove.com>
* *
* Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
* *
...@@ -85,6 +87,10 @@ ...@@ -85,6 +87,10 @@
#define SONYPI_EVENT_JOGDIAL_VFAST_UP 47 #define SONYPI_EVENT_JOGDIAL_VFAST_UP 47
#define SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED 48 #define SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED 48
#define SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED 49 #define SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED 49
#define SONYPI_EVENT_ZOOM_PRESSED 50
#define SONYPI_EVENT_THUMBPHRASE_PRESSED 51
#define SONYPI_EVENT_MEYE_FACE 52
#define SONYPI_EVENT_MEYE_OPPOSITE 53
/* get/set brightness */ /* get/set brightness */
#define SONYPI_IOCGBRT _IOR('v', 0, __u8) #define SONYPI_IOCGBRT _IOR('v', 0, __u8)
......
...@@ -155,6 +155,93 @@ typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len); ...@@ -155,6 +155,93 @@ typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int, extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
skb_reader_t *, skb_read_actor_t); skb_reader_t *, skb_read_actor_t);
/*
* Provide some simple tools for XDR buffer overflow-checking etc.
*/
struct xdr_stream {
uint32_t *p; /* start of available buffer */
struct xdr_buf *buf; /* XDR buffer to read/write */
uint32_t *end; /* end of available buffer space */
struct iovec *iov; /* pointer to the current iovec */
};
/*
* Initialize an xdr_stream for encoding data.
*
* Note: at the moment the RPC client only passes the length of our
* scratch buffer in the xdr_buf's header iovec. Previously this
* meant we needed to call xdr_adjust_iovec() after encoding the
* data. With the new scheme, the xdr_stream manages the details
* of the buffer length, and takes care of adjusting the iovec
* length for us.
*/
static inline void
xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
xdr->buf = buf;
xdr->iov = iov;
xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base;
xdr->p = p;
}
/*
* Check that we have enough buffer space to encode 'nbytes' more
* bytes of data. If so, update the total xdr_buf length, and
* adjust the length of the current iovec.
*/
static inline uint32_t *
xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q;
/* align nbytes on the next 32-bit boundary */
nbytes += 3;
nbytes &= ~3;
q = p + (nbytes >> 2);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
xdr->iov->iov_len += nbytes;
xdr->buf->len += nbytes;
return p;
}
/*
* Initialize an xdr_stream for decoding data.
*/
static inline void
xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
xdr->buf = buf;
xdr->iov = iov;
xdr->p = p;
xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
}
/*
* Check if the input buffer is long enough to enable us to decode
* 'nbytes' more bytes of data starting at the current position.
* If so return the current pointer, then update the current
* position.
*/
static inline uint32_t *
xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q = p + XDR_QUADLEN(nbytes);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
return p;
}
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _SUNRPC_XDR_H_ */ #endif /* _SUNRPC_XDR_H_ */
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (C) 2001 Russell King * Copyright (C) 2001 Russell King
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
* *
* $Id: cpufreq.c,v 1.45 2002/10/08 14:54:23 db Exp $ * $Id: cpufreq.c,v 1.50 2002/11/11 15:35:48 db Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -69,8 +69,8 @@ static struct cpufreq_policy default_policy = { ...@@ -69,8 +69,8 @@ static struct cpufreq_policy default_policy = {
/** /**
* A few values needed by the 2.4.-compatible API * A few values needed by the 2.4.-compatible API
*/ */
static unsigned int cpu_max_freq; static unsigned int cpu_max_freq[NR_CPUS];
static unsigned int cpu_min_freq; static unsigned int cpu_min_freq[NR_CPUS];
static unsigned int cpu_cur_freq[NR_CPUS]; static unsigned int cpu_cur_freq[NR_CPUS];
#endif #endif
...@@ -228,6 +228,10 @@ static int cpufreq_proc_read ( ...@@ -228,6 +228,10 @@ static int cpufreq_proc_read (
continue; continue;
cpufreq_get_policy(&policy, i); cpufreq_get_policy(&policy, i);
if (!policy.max_cpu_freq)
continue;
min_pctg = (policy.min * 100) / policy.max_cpu_freq; min_pctg = (policy.min * 100) / policy.max_cpu_freq;
max_pctg = (policy.max * 100) / policy.max_cpu_freq; max_pctg = (policy.max * 100) / policy.max_cpu_freq;
...@@ -378,7 +382,7 @@ int cpufreq_setmax(unsigned int cpu) ...@@ -378,7 +382,7 @@ int cpufreq_setmax(unsigned int cpu)
{ {
if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS)) if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS))
return -EINVAL; return -EINVAL;
return cpufreq_set(cpu_max_freq, cpu); return cpufreq_set(cpu_max_freq[cpu], cpu);
} }
EXPORT_SYMBOL_GPL(cpufreq_setmax); EXPORT_SYMBOL_GPL(cpufreq_setmax);
...@@ -807,13 +811,14 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) ...@@ -807,13 +811,14 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
policy->min = cpufreq_driver->policy[cpu].min; policy->min = cpufreq_driver->policy[cpu].min;
policy->max = cpufreq_driver->policy[cpu].max; policy->max = cpufreq_driver->policy[cpu].max;
policy->policy = cpufreq_driver->policy[cpu].policy; policy->policy = cpufreq_driver->policy[cpu].policy;
policy->max_cpu_freq = cpufreq_driver->policy[0].max_cpu_freq; policy->max_cpu_freq = cpufreq_driver->policy[cpu].max_cpu_freq;
policy->cpu = cpu; policy->cpu = cpu;
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
return 0; return 0;
} }
EXPORT_SYMBOL(cpufreq_get_policy);
/** /**
...@@ -825,6 +830,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) ...@@ -825,6 +830,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
int cpufreq_set_policy(struct cpufreq_policy *policy) int cpufreq_set_policy(struct cpufreq_policy *policy)
{ {
unsigned int i; unsigned int i;
int ret;
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
if (!cpufreq_driver || !cpufreq_driver->verify || if (!cpufreq_driver || !cpufreq_driver->verify ||
...@@ -834,12 +840,20 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) ...@@ -834,12 +840,20 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
return -EINVAL; return -EINVAL;
} }
down(&cpufreq_notifier_sem); if (policy->cpu == CPUFREQ_ALL_CPUS)
policy->max_cpu_freq = cpufreq_driver->policy[0].max_cpu_freq;
else
policy->max_cpu_freq = cpufreq_driver->policy[policy->cpu].max_cpu_freq;
policy->max_cpu_freq = cpufreq_driver->policy[0].max_cpu_freq;
/* verify the cpu speed can be set within this limit */ /* verify the cpu speed can be set within this limit */
cpufreq_driver->verify(policy); ret = cpufreq_driver->verify(policy);
if (ret) {
up(&cpufreq_driver_sem);
return ret;
}
down(&cpufreq_notifier_sem);
/* adjust if neccessary - all reasons */ /* adjust if neccessary - all reasons */
notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST, notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST,
...@@ -851,7 +865,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) ...@@ -851,7 +865,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
/* verify the cpu speed can be set within this limit, /* verify the cpu speed can be set within this limit,
which might be different to the first one */ which might be different to the first one */
cpufreq_driver->verify(policy); ret = cpufreq_driver->verify(policy);
if (ret) {
up(&cpufreq_notifier_sem);
up(&cpufreq_driver_sem);
return ret;
}
/* notification of the new policy */ /* notification of the new policy */
notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY, notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY,
...@@ -879,11 +898,11 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) ...@@ -879,11 +898,11 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
cpu_cur_freq[policy->cpu] = policy->max; cpu_cur_freq[policy->cpu] = policy->max;
#endif #endif
cpufreq_driver->setpolicy(policy); ret = cpufreq_driver->setpolicy(policy);
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
return 0; return ret;
} }
EXPORT_SYMBOL(cpufreq_set_policy); EXPORT_SYMBOL(cpufreq_set_policy);
...@@ -968,6 +987,8 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition); ...@@ -968,6 +987,8 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
int cpufreq_register(struct cpufreq_driver *driver_data) int cpufreq_register(struct cpufreq_driver *driver_data)
{ {
unsigned int ret; unsigned int ret;
unsigned int i;
struct cpufreq_policy policy;
if (cpufreq_driver) if (cpufreq_driver)
return -EBUSY; return -EBUSY;
...@@ -979,41 +1000,55 @@ int cpufreq_register(struct cpufreq_driver *driver_data) ...@@ -979,41 +1000,55 @@ int cpufreq_register(struct cpufreq_driver *driver_data)
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
cpufreq_driver = driver_data; cpufreq_driver = driver_data;
if (!default_policy.policy) /* check for a default policy - if it exists, use it on _all_ CPUs*/
default_policy.policy = driver_data->policy[0].policy; for (i=0; i<NR_CPUS; i++)
if (!default_policy.min) {
default_policy.min = driver_data->policy[0].min; if (default_policy.policy)
if (!default_policy.max) cpufreq_driver->policy[i].policy = default_policy.policy;
default_policy.max = driver_data->policy[0].max; if (default_policy.min)
default_policy.cpu = CPUFREQ_ALL_CPUS; cpufreq_driver->policy[i].min = default_policy.min;
if (default_policy.max)
cpufreq_driver->policy[i].max = default_policy.max;
}
up(&cpufreq_driver_sem); /* set default policy on all CPUs. Must be called per-CPU and not
* with CPUFREQ_ALL_CPUs as there might be no common policy for all
* CPUs (UltraSPARC etc.)
*/
for (i=0; i<NR_CPUS; i++)
{
policy.policy = cpufreq_driver->policy[i].policy;
policy.min = cpufreq_driver->policy[i].min;
policy.max = cpufreq_driver->policy[i].max;
policy.cpu = i;
up(&cpufreq_driver_sem);
ret = cpufreq_set_policy(&policy);
down(&cpufreq_driver_sem);
if (ret) {
cpufreq_driver = NULL;
up(&cpufreq_driver_sem);
return ret;
}
}
ret = cpufreq_set_policy(&default_policy); up(&cpufreq_driver_sem);
cpufreq_proc_init(); cpufreq_proc_init();
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
cpu_min_freq = driver_data->cpu_min_freq; for (i=0; i<NR_CPUS; i++)
cpu_max_freq = driver_data->policy[0].max_cpu_freq;
{ {
unsigned int i; cpu_min_freq[i] = driver_data->cpu_min_freq[i];
for (i=0; i<NR_CPUS; i++) { cpu_max_freq[i] = driver_data->policy[i].max_cpu_freq;
cpu_cur_freq[i] = driver_data->cpu_cur_freq[i]; cpu_cur_freq[i] = driver_data->cpu_cur_freq[i];
}
} }
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
cpufreq_sysctl_init(); cpufreq_sysctl_init();
#endif #endif
if (ret) {
down(&cpufreq_driver_sem);
cpufreq_driver = NULL;
up(&cpufreq_driver_sem);
}
return ret; return 0;
} }
EXPORT_SYMBOL_GPL(cpufreq_register); EXPORT_SYMBOL_GPL(cpufreq_register);
...@@ -1061,6 +1096,7 @@ int cpufreq_restore(void) ...@@ -1061,6 +1096,7 @@ int cpufreq_restore(void)
{ {
struct cpufreq_policy policy; struct cpufreq_policy policy;
unsigned int i; unsigned int i;
unsigned int ret = 0;
if (in_interrupt()) if (in_interrupt())
panic("cpufreq_restore() called from interrupt context!"); panic("cpufreq_restore() called from interrupt context!");
...@@ -1081,10 +1117,10 @@ int cpufreq_restore(void) ...@@ -1081,10 +1117,10 @@ int cpufreq_restore(void)
policy.cpu = i; policy.cpu = i;
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
cpufreq_set_policy(&policy); ret += cpufreq_set_policy(&policy);
} }
return 0; return ret;
} }
EXPORT_SYMBOL_GPL(cpufreq_restore); EXPORT_SYMBOL_GPL(cpufreq_restore);
#else #else
......
...@@ -182,9 +182,10 @@ static inline int ip6_input_finish(struct sk_buff *skb) ...@@ -182,9 +182,10 @@ static inline int ip6_input_finish(struct sk_buff *skb)
if (!raw_sk) { if (!raw_sk) {
IP6_INC_STATS_BH(Ip6InUnknownProtos); IP6_INC_STATS_BH(Ip6InUnknownProtos);
icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff); icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff);
} else } else {
IP6_INC_STATS_BH(Ip6InDelivers); IP6_INC_STATS_BH(Ip6InDelivers);
kfree_skb(skb); kfree_skb(skb);
}
} }
return 0; return 0;
......
...@@ -116,6 +116,7 @@ EXPORT_SYMBOL(sock_sendmsg); ...@@ -116,6 +116,7 @@ EXPORT_SYMBOL(sock_sendmsg);
EXPORT_SYMBOL(sock_recvmsg); EXPORT_SYMBOL(sock_recvmsg);
EXPORT_SYMBOL(sk_alloc); EXPORT_SYMBOL(sk_alloc);
EXPORT_SYMBOL(sk_free); EXPORT_SYMBOL(sk_free);
EXPORT_SYMBOL(sk_send_sigurg);
EXPORT_SYMBOL(sock_wake_async); EXPORT_SYMBOL(sock_wake_async);
EXPORT_SYMBOL(sock_alloc_send_skb); EXPORT_SYMBOL(sock_alloc_send_skb);
EXPORT_SYMBOL(sock_alloc_send_pskb); EXPORT_SYMBOL(sock_alloc_send_pskb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment