lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <200704131022.45315.rjw@sisk.pl>
Date:	Fri, 13 Apr 2007 10:22:44 +0200
From:	"Rafael J. Wysocki" <rjw@...k.pl>
To:	"Robert P. J. Day" <rpjday@...dspring.com>
Cc:	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	pm list <linux-pm@...ts.linux-foundation.org>,
	Pavel Machek <pavel@....cz>
Subject: Re: [PATCH][RFC] Kill off legacy power management stuff.

[appropriate CCs added]

On Friday, 13 April 2007 02:33, Robert P. J. Day wrote:
> 
> just something i threw together, not in final form, but it represents
> tossing the legacy PM stuff.  at the moment, the menuconfig entry for
> PM_LEGACY lists it as "DEPRECATED", while the help screen calls it
> "obsolete."  that's a good sign that it's getting close to the time
> for it to go, and the removal is fairly straightforward, but there's
> no mention of its removal in the feature removal schedule file.

It's been like this for a long long time.  I think you're right that it can be
dropped, but I don't know the details (eg. why it hasn't been dropped yet).
 
> NOTE:  this is not a working patch as it will fail on a MIPS or FR-V
> build, as i didn't remove the final vestiges from those two
> architectures.  that would require simply killing off the remaining
> calls to pm_send_all(), that's all.  (i think.)
> 
> anyway, this has been compile-tested on x86 with "make allyesconfig."
> 
> 
>  Documentation/pm.txt         |  123 -------------------
>  arch/i386/kernel/apm.c       |   27 ----
>  drivers/acpi/bus.c           |   14 --
>  drivers/net/3c509.c          |    1
>  drivers/serial/68328serial.c |   59 ---------
>  include/linux/pm.h           |   70 -----------
>  include/linux/pm_legacy.h    |   41 ------
>  kernel/power/Kconfig         |   10 -
>  kernel/power/Makefile        |    1
>  kernel/power/pm.c            |  209 ---------------------------------
>  10 files changed, 1 insertion(+), 554 deletions(-)
> 
> 
> diff --git a/Documentation/pm.txt b/Documentation/pm.txt
> index da8589a..d0fcfe2 100644
> --- a/Documentation/pm.txt
> +++ b/Documentation/pm.txt
> @@ -36,93 +36,6 @@ system the associated daemon will exit gracefully.
>    apmd:   http://worldvisions.ca/~apenwarr/apmd/
>    acpid:  http://acpid.sf.net/
> 
> -Driver Interface -- OBSOLETE, DO NOT USE!
> -----------------*************************
> -
> -Note: pm_register(), pm_access(), pm_dev_idle() and friends are
> -obsolete. Please do not use them. Instead you should properly hook
> -your driver into the driver model, and use its suspend()/resume()
> -callbacks to do this kind of stuff.
> -
> -If you are writing a new driver or maintaining an old driver, it
> -should include power management support.  Without power management
> -support, a single driver may prevent a system with power management
> -capabilities from ever being able to suspend (safely).
> -
> -Overview:
> -1) Register each instance of a device with "pm_register"
> -2) Call "pm_access" before accessing the hardware.
> -   (this will ensure that the hardware is awake and ready)
> -3) Your "pm_callback" is called before going into a
> -   suspend state (ACPI D1-D3) or after resuming (ACPI D0)
> -   from a suspend.
> -4) Call "pm_dev_idle" when the device is not being used
> -   (optional but will improve device idle detection)
> -5) When unloaded, unregister the device with "pm_unregister"
> -
> -/*
> - * Description: Register a device with the power-management subsystem
> - *
> - * Parameters:
> - *   type - device type (PCI device, system device, ...)
> - *   id - instance number or unique identifier
> - *   cback - request handler callback (suspend, resume, ...)
> - *
> - * Returns: Registered PM device or NULL on error
> - *
> - * Examples:
> - *   dev = pm_register(PM_SYS_DEV, PM_SYS_VGA, vga_callback);
> - *
> - *   struct pci_dev *pci_dev = pci_find_dev(...);
> - *   dev = pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev), callback);
> - */
> -struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback cback);
> -
> -/*
> - * Description: Unregister a device with the power management subsystem
> - *
> - * Parameters:
> - *   dev - PM device previously returned from pm_register
> - */
> -void pm_unregister(struct pm_dev *dev);
> -
> -/*
> - * Description: Unregister all devices with a matching callback function
> - *
> - * Parameters:
> - *   cback - previously registered request callback
> - *
> - * Notes: Provided for easier porting from old APM interface
> - */
> -void pm_unregister_all(pm_callback cback);
> -
> -/*
> - * Power management request callback
> - *
> - * Parameters:
> - *   dev - PM device previously returned from pm_register
> - *   rqst - request type
> - *   data - data, if any, associated with the request
> - *
> - * Returns: 0 if the request is successful
> - *          EINVAL if the request is not supported
> - *          EBUSY if the device is now busy and cannot handle the request
> - *          ENOMEM if the device was unable to handle the request due to memory
> - *
> - * Details: The device request callback will be called before the
> - *          device/system enters a suspend state (ACPI D1-D3) or
> - *          or after the device/system resumes from suspend (ACPI D0).
> - *          For PM_SUSPEND, the ACPI D-state being entered is passed
> - *          as the "data" argument to the callback.  The device
> - *          driver should save (PM_SUSPEND) or restore (PM_RESUME)
> - *          device context when the request callback is called.
> - *
> - *          Once a driver returns 0 (success) from a suspend
> - *          request, it should not process any further requests or
> - *          access the device hardware until a call to "pm_access" is made.
> - */
> -typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);
> -
>  Driver Details
>  --------------
>  This is just a quick Q&A as a stopgap until a real driver writers'
> @@ -219,39 +132,3 @@ Q: Who do I contact for additional information about
>     enabling power management for my specific driver/device?
> 
>  ACPI Development mailing list: linux-acpi@...r.kernel.org
> -
> -System Interface -- OBSOLETE, DO NOT USE!
> -----------------*************************
> -If you are providing new power management support to Linux (ie.
> -adding support for something like APM or ACPI), you should
> -communicate with drivers through the existing generic power
> -management interface.
> -
> -/*
> - * Send a request to all devices
> - *
> - * Parameters:
> - *   rqst - request type
> - *   data - data, if any, associated with the request
> - *
> - * Returns: 0 if the request is successful
> - *          See "pm_callback" return for errors
> - *
> - * Details: Walk list of registered devices and call pm_send
> - *          for each until complete or an error is encountered.
> - *          If an error is encountered for a suspend request,
> - *          return all devices to the state they were in before
> - *          the suspend request.
> - */
> -int pm_send_all(pm_request_t rqst, void *data);
> -
> -/*
> - * Find a matching device
> - *
> - * Parameters:
> - *   type - device type (PCI device, system device, or 0 to match all devices)
> - *   from - previous match or NULL to start from the beginning
> - *
> - * Returns: Matching device or NULL if none found
> - */
> -struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from);
> diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
> index 064bbf2..46c3ee6 100644
> --- a/arch/i386/kernel/apm.c
> +++ b/arch/i386/kernel/apm.c
> @@ -218,7 +218,6 @@
>  #include <linux/time.h>
>  #include <linux/sched.h>
>  #include <linux/pm.h>
> -#include <linux/pm_legacy.h>
>  #include <linux/capability.h>
>  #include <linux/device.h>
>  #include <linux/kernel.h>
> @@ -1197,19 +1196,6 @@ static int suspend(int vetoable)
>  	int		err;
>  	struct apm_user	*as;
> 
> -	if (pm_send_all(PM_SUSPEND, (void *)3)) {
> -		/* Vetoed */
> -		if (vetoable) {
> -			if (apm_info.connection_version > 0x100)
> -				set_system_power_state(APM_STATE_REJECT);
> -			err = -EBUSY;
> -			ignore_sys_suspend = 0;
> -			printk(KERN_WARNING "apm: suspend was vetoed.\n");
> -			goto out;
> -		}
> -		printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
> -	}
> -
>  	device_suspend(PMSG_SUSPEND);
>  	local_irq_disable();
>  	device_power_down(PMSG_SUSPEND);
> @@ -1232,7 +1218,6 @@ static int suspend(int vetoable)
>  	device_power_up();
>  	local_irq_enable();
>  	device_resume();
> -	pm_send_all(PM_RESUME, (void *)0);
>  	queue_event(APM_NORMAL_RESUME, NULL);
>   out:
>  	spin_lock(&user_list_lock);
> @@ -1345,7 +1330,6 @@ static void check_events(void)
>  			if ((event != APM_NORMAL_RESUME)
>  			    || (ignore_normal_resume == 0)) {
>  				device_resume();
> -				pm_send_all(PM_RESUME, (void *)0);
>  				queue_event(event, NULL);
>  			}
>  			ignore_normal_resume = 0;
> @@ -2264,14 +2248,6 @@ static int __init apm_init(void)
>  		apm_info.disabled = 1;
>  		return -ENODEV;
>  	}
> -	if (PM_IS_ACTIVE()) {
> -		printk(KERN_NOTICE "apm: overridden by ACPI.\n");
> -		apm_info.disabled = 1;
> -		return -ENODEV;
> -	}
> -#ifdef CONFIG_PM_LEGACY
> -	pm_active = 1;
> -#endif
> 
>  	/*
>  	 * Set up a segment that references the real mode segment 0x40
> @@ -2375,9 +2351,6 @@ static void __exit apm_exit(void)
>  		kthread_stop(kapmd_task);
>  		kapmd_task = NULL;
>  	}
> -#ifdef CONFIG_PM_LEGACY
> -	pm_active = 0;
> -#endif
>  }
> 
>  module_init(apm_init);
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index dd49ea0..b3e92b4 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -29,7 +29,6 @@
>  #include <linux/list.h>
>  #include <linux/sched.h>
>  #include <linux/pm.h>
> -#include <linux/pm_legacy.h>
>  #include <linux/device.h>
>  #include <linux/proc_fs.h>
>  #ifdef CONFIG_X86
> @@ -752,18 +751,7 @@ static int __init acpi_init(void)
> 
>  	result = acpi_bus_init();
> 
> -	if (!result) {
> -#ifdef CONFIG_PM_LEGACY
> -		if (!PM_IS_ACTIVE())
> -			pm_active = 1;
> -		else {
> -			printk(KERN_INFO PREFIX
> -			       "APM is already active, exiting\n");
> -			disable_acpi();
> -			result = -ENODEV;
> -		}
> -#endif
> -	} else
> +	if (result)
>  		disable_acpi();
> 
>  	return result;
> diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
> index f791bf0..a8ea346 100644
> --- a/drivers/net/3c509.c
> +++ b/drivers/net/3c509.c
> @@ -83,7 +83,6 @@ static int max_interrupt_work = 10;
>  #include <linux/netdevice.h>
>  #include <linux/etherdevice.h>
>  #include <linux/pm.h>
> -#include <linux/pm_legacy.h>
>  #include <linux/skbuff.h>
>  #include <linux/delay.h>	/* for udelay() */
>  #include <linux/spinlock.h>
> diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
> index cad426c..151bd9a 100644
> --- a/drivers/serial/68328serial.c
> +++ b/drivers/serial/68328serial.c
> @@ -33,7 +33,6 @@
>  #include <linux/keyboard.h>
>  #include <linux/init.h>
>  #include <linux/pm.h>
> -#include <linux/pm_legacy.h>
>  #include <linux/bitops.h>
>  #include <linux/delay.h>
> 
> @@ -1324,59 +1323,6 @@ static void show_serial_version(void)
>  	printk("MC68328 serial driver version 1.00\n");
>  }
> 
> -#ifdef CONFIG_PM_LEGACY
> -/* Serial Power management
> - *  The console (currently fixed at line 0) is a special case for power
> - *  management because the kernel is so chatty. The console will be
> - *  explicitly disabled my our power manager as the last minute, so we won't
> - *  mess with it here.
> - */
> -static struct pm_dev *serial_pm[NR_PORTS];
> -
> -static int serial_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
> -{
> -	struct m68k_serial *info = (struct m68k_serial *)dev->data;
> -
> -	if(info == NULL)
> -		return -1;
> -
> -	/* special case for line 0 - pm restores it */
> -	if(info->line == 0)
> -		return 0;
> -
> -	switch (request) {
> -	case PM_SUSPEND:
> -		shutdown(info);
> -		break;
> -
> -	case PM_RESUME:
> -		startup(info);
> -		break;
> -	}
> -	return 0;
> -}
> -
> -void shutdown_console(void)
> -{
> -	struct m68k_serial *info = &m68k_soft[0];
> -
> -	/* HACK: wait a bit for any pending printk's to be dumped */
> -	{
> -		int i = 10000;
> -		while(i--);
> -	}
> -
> -	shutdown(info);
> -}
> -
> -void startup_console(void)
> -{
> -	struct m68k_serial *info = &m68k_soft[0];
> -	startup(info);
> -}
> -#endif /* CONFIG_PM_LEGACY */
> -
> -
>  static const struct tty_operations rs_ops = {
>  	.open = rs_open,
>  	.close = rs_close,
> @@ -1467,11 +1413,6 @@ rs68328_init(void)
>  			    IRQ_FLG_STD,
>  			    "M68328_UART", NULL))
>                  panic("Unable to attach 68328 serial interrupt\n");
> -#ifdef CONFIG_PM_LEGACY
> -	    serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback);
> -	    if (serial_pm[i])
> -		    serial_pm[i]->data = info;
> -#endif
>  	}
>  	local_irq_restore(flags);
>  	return 0;
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 21db05a..c505f89 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -27,76 +27,6 @@
>  #include <asm/atomic.h>
> 
>  /*
> - * Power management requests... these are passed to pm_send_all() and friends.
> - *
> - * these functions are old and deprecated, see below.
> - */
> -typedef int __bitwise pm_request_t;
> -
> -#define PM_SUSPEND	((__force pm_request_t) 1)	/* enter D1-D3 */
> -#define PM_RESUME	((__force pm_request_t) 2)	/* enter D0 */
> -
> -
> -/*
> - * Device types... these are passed to pm_register
> - */
> -typedef int __bitwise pm_dev_t;
> -
> -#define PM_UNKNOWN_DEV	((__force pm_dev_t) 0)	/* generic */
> -#define PM_SYS_DEV	((__force pm_dev_t) 1)	/* system device (fan, KB controller, ...) */
> -#define PM_PCI_DEV	((__force pm_dev_t) 2)	/* PCI device */
> -#define PM_USB_DEV	((__force pm_dev_t) 3)	/* USB device */
> -#define PM_SCSI_DEV	((__force pm_dev_t) 4)	/* SCSI device */
> -#define PM_ISA_DEV	((__force pm_dev_t) 5)	/* ISA device */
> -#define	PM_MTD_DEV	((__force pm_dev_t) 6)	/* Memory Technology Device */
> -
> -/*
> - * System device hardware ID (PnP) values
> - */
> -enum
> -{
> -	PM_SYS_UNKNOWN = 0x00000000, /* generic */
> -	PM_SYS_KBC =	 0x41d00303, /* keyboard controller */
> -	PM_SYS_COM =	 0x41d00500, /* serial port */
> -	PM_SYS_IRDA =	 0x41d00510, /* IRDA controller */
> -	PM_SYS_FDC =	 0x41d00700, /* floppy controller */
> -	PM_SYS_VGA =	 0x41d00900, /* VGA controller */
> -	PM_SYS_PCMCIA =	 0x41d00e00, /* PCMCIA controller */
> -};
> -
> -/*
> - * Device identifier
> - */
> -#define PM_PCI_ID(dev) ((dev)->bus->number << 16 | (dev)->devfn)
> -
> -/*
> - * Request handler callback
> - */
> -struct pm_dev;
> -
> -typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);
> -
> -/*
> - * Dynamic device information
> - */
> -struct pm_dev
> -{
> -	pm_dev_t	 type;
> -	unsigned long	 id;
> -	pm_callback	 callback;
> -	void		*data;
> -
> -	unsigned long	 flags;
> -	unsigned long	 state;
> -	unsigned long	 prev_state;
> -
> -	struct list_head entry;
> -};
> -
> -/* Functions above this comment are list-based old-style power
> - * managment. Please avoid using them.  */
> -
> -/*
>   * Callbacks for platform drivers to implement.
>   */
>  extern void (*pm_idle)(void);
> diff --git a/include/linux/pm_legacy.h b/include/linux/pm_legacy.h
> deleted file mode 100644
> index 514729a..0000000
> --- a/include/linux/pm_legacy.h
> +++ /dev/null
> @@ -1,41 +0,0 @@
> -#ifndef __LINUX_PM_LEGACY_H__
> -#define __LINUX_PM_LEGACY_H__
> -
> -
> -#ifdef CONFIG_PM_LEGACY
> -
> -extern int pm_active;
> -
> -#define PM_IS_ACTIVE() (pm_active != 0)
> -
> -/*
> - * Register a device with power management
> - */
> -struct pm_dev __deprecated *
> -pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
> -
> -/*
> - * Send a request to all devices
> - */
> -int __deprecated pm_send_all(pm_request_t rqst, void *data);
> -
> -#else /* CONFIG_PM_LEGACY */
> -
> -#define PM_IS_ACTIVE() 0
> -
> -static inline struct pm_dev *pm_register(pm_dev_t type,
> -					 unsigned long id,
> -					 pm_callback callback)
> -{
> -	return NULL;
> -}
> -
> -static inline int pm_send_all(pm_request_t rqst, void *data)
> -{
> -	return 0;
> -}
> -
> -#endif /* CONFIG_PM_LEGACY */
> -
> -#endif /* __LINUX_PM_LEGACY_H__ */
> -
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 51a4dd0..7ade6eb 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -19,16 +19,6 @@ config PM
>  	  will issue the hlt instruction if nothing is to be done, thereby
>  	  sending the processor to sleep and saving power.
> 
> -config PM_LEGACY
> -	bool "Legacy Power Management API (DEPRECATED)"
> -	depends on PM
> -	default n
> -	---help---
> -	   Support for pm_register() and friends.  This old API is obsoleted
> -	   by the driver model.
> -
> -	   If unsure, say N.
> -
>  config PM_DEBUG
>  	bool "Power Management Debug Support"
>  	depends on PM
> diff --git a/kernel/power/Makefile b/kernel/power/Makefile
> index 38725f5..846b303 100644
> --- a/kernel/power/Makefile
> +++ b/kernel/power/Makefile
> @@ -4,7 +4,6 @@ EXTRA_CFLAGS	+=	-DDEBUG
>  endif
> 
>  obj-y				:= main.o process.o console.o
> -obj-$(CONFIG_PM_LEGACY)		+= pm.o
>  obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o disk.o snapshot.o swap.o user.o
> 
>  obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
> diff --git a/kernel/power/pm.c b/kernel/power/pm.c
> deleted file mode 100644
> index c50d152..0000000
> --- a/kernel/power/pm.c
> +++ /dev/null
> @@ -1,209 +0,0 @@
> -/*
> - *  pm.c - Power management interface
> - *
> - *  Copyright (C) 2000 Andrew Henroid
> - *
> - *  This program is free software; you can redistribute it and/or modify
> - *  it under the terms of the GNU General Public License as published by
> - *  the Free Software Foundation; either version 2 of the License, or
> - *  (at your option) any later version.
> - *
> - *  This program is distributed in the hope that it will be useful,
> - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *  GNU General Public License for more details.
> - *
> - *  You should have received a copy of the GNU General Public License
> - *  along with this program; if not, write to the Free Software
> - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> - */
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/spinlock.h>
> -#include <linux/mm.h>
> -#include <linux/slab.h>
> -#include <linux/pm.h>
> -#include <linux/pm_legacy.h>
> -#include <linux/interrupt.h>
> -#include <linux/mutex.h>
> -
> -int pm_active;
> -
> -/*
> - *	Locking notes:
> - *		pm_devs_lock can be a semaphore providing pm ops are not called
> - *	from an interrupt handler (already a bad idea so no change here). Each
> - *	change must be protected so that an unlink of an entry doesn't clash
> - *	with a pm send - which is permitted to sleep in the current architecture
> - *
> - *	Module unloads clashing with pm events now work out safely, the module
> - *	unload path will block until the event has been sent. It may well block
> - *	until a resume but that will be fine.
> - */
> -
> -static DEFINE_MUTEX(pm_devs_lock);
> -static LIST_HEAD(pm_devs);
> -
> -/**
> - *	pm_register - register a device with power management
> - *	@type: device type
> - *	@id: device ID
> - *	@callback: callback function
> - *
> - *	Add a device to the list of devices that wish to be notified about
> - *	power management events. A &pm_dev structure is returned on success,
> - *	on failure the return is %NULL.
> - *
> - *      The callback function will be called in process context and
> - *      it may sleep.
> - */
> -
> -struct pm_dev *pm_register(pm_dev_t type,
> -			   unsigned long id,
> -			   pm_callback callback)
> -{
> -	struct pm_dev *dev = kzalloc(sizeof(struct pm_dev), GFP_KERNEL);
> -	if (dev) {
> -		dev->type = type;
> -		dev->id = id;
> -		dev->callback = callback;
> -
> -		mutex_lock(&pm_devs_lock);
> -		list_add(&dev->entry, &pm_devs);
> -		mutex_unlock(&pm_devs_lock);
> -	}
> -	return dev;
> -}
> -
> -/**
> - *	pm_send - send request to a single device
> - *	@dev: device to send to
> - *	@rqst: power management request
> - *	@data: data for the callback
> - *
> - *	Issue a power management request to a given device. The
> - *	%PM_SUSPEND and %PM_RESUME events are handled specially. The
> - *	data field must hold the intended next state. No call is made
> - *	if the state matches.
> - *
> - *	BUGS: what stops two power management requests occurring in parallel
> - *	and conflicting.
> - *
> - *	WARNING: Calling pm_send directly is not generally recommended, in
> - *	particular there is no locking against the pm_dev going away. The
> - *	caller must maintain all needed locking or have 'inside knowledge'
> - *	on the safety. Also remember that this function is not locked against
> - *	pm_unregister. This means that you must handle SMP races on callback
> - *	execution and unload yourself.
> - */
> -
> -static int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data)
> -{
> -	int status = 0;
> -	unsigned long prev_state, next_state;
> -
> -	if (in_interrupt())
> -		BUG();
> -
> -	switch (rqst) {
> -	case PM_SUSPEND:
> -	case PM_RESUME:
> -		prev_state = dev->state;
> -		next_state = (unsigned long) data;
> -		if (prev_state != next_state) {
> -			if (dev->callback)
> -				status = (*dev->callback)(dev, rqst, data);
> -			if (!status) {
> -				dev->state = next_state;
> -				dev->prev_state = prev_state;
> -			}
> -		}
> -		else {
> -			dev->prev_state = prev_state;
> -		}
> -		break;
> -	default:
> -		if (dev->callback)
> -			status = (*dev->callback)(dev, rqst, data);
> -		break;
> -	}
> -	return status;
> -}
> -
> -/*
> - * Undo incomplete request
> - */
> -static void pm_undo_all(struct pm_dev *last)
> -{
> -	struct list_head *entry = last->entry.prev;
> -	while (entry != &pm_devs) {
> -		struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
> -		if (dev->state != dev->prev_state) {
> -			/* previous state was zero (running) resume or
> -			 * previous state was non-zero (suspended) suspend
> -			 */
> -			pm_request_t undo = (dev->prev_state
> -					     ? PM_SUSPEND:PM_RESUME);
> -			pm_send(dev, undo, (void*) dev->prev_state);
> -		}
> -		entry = entry->prev;
> -	}
> -}
> -
> -/**
> - *	pm_send_all - send request to all managed devices
> - *	@rqst: power management request
> - *	@data: data for the callback
> - *
> - *	Issue a power management request to a all devices. The
> - *	%PM_SUSPEND events are handled specially. Any device is
> - *	permitted to fail a suspend by returning a non zero (error)
> - *	value from its callback function. If any device vetoes a
> - *	suspend request then all other devices that have suspended
> - *	during the processing of this request are restored to their
> - *	previous state.
> - *
> - *	WARNING:  This function takes the pm_devs_lock. The lock is not dropped until
> - *	the callbacks have completed. This prevents races against pm locking
> - *	functions, races against module unload pm_unregister code. It does
> - *	mean however that you must not issue pm_ functions within the callback
> - *	or you will deadlock and users will hate you.
> - *
> - *	Zero is returned on success. If a suspend fails then the status
> - *	from the device that vetoes the suspend is returned.
> - *
> - *	BUGS: what stops two power management requests occurring in parallel
> - *	and conflicting.
> - */
> -
> -int pm_send_all(pm_request_t rqst, void *data)
> -{
> -	struct list_head *entry;
> -
> -	mutex_lock(&pm_devs_lock);
> -	entry = pm_devs.next;
> -	while (entry != &pm_devs) {
> -		struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
> -		if (dev->callback) {
> -			int status = pm_send(dev, rqst, data);
> -			if (status) {
> -				/* return devices to previous state on
> -				 * failed suspend request
> -				 */
> -				if (rqst == PM_SUSPEND)
> -					pm_undo_all(dev);
> -				mutex_unlock(&pm_devs_lock);
> -				return status;
> -			}
> -		}
> -		entry = entry->next;
> -	}
> -	mutex_unlock(&pm_devs_lock);
> -	return 0;
> -}
> -
> -EXPORT_SYMBOL(pm_register);
> -EXPORT_SYMBOL(pm_send_all);
> -EXPORT_SYMBOL(pm_active);
> -
> -
> 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ