diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index 7cefb30cb425..f795e0036f9f 100644 --- a/sys/dev/cardbus/cardbus.c +++ b/sys/dev/cardbus/cardbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: cardbus.c,v 1.89 2008/02/23 00:30:56 dyoung Exp $ */ +/* $NetBSD: cardbus.c,v 1.90 2008/02/28 14:25:12 drochner Exp $ */ /* * Copyright (c) 1997, 1998, 1999 and 2000 @@ -33,7 +33,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cardbus.c,v 1.89 2008/02/23 00:30:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cardbus.c,v 1.90 2008/02/28 14:25:12 drochner Exp $"); #include "opt_cardbus.h" @@ -1243,7 +1243,7 @@ cardbus_child_register(device_t child) } device_pmf_bus_register(child, priv, cardbus_child_suspend, - cardbus_child_resume, cardbus_child_deregister); + cardbus_child_resume, 0, cardbus_child_deregister); return true; } diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index fc747a0b1cd9..8331a10a5b77 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: pci.c,v 1.112 2008/02/23 00:27:53 dyoung Exp $ */ +/* $NetBSD: pci.c,v 1.113 2008/02/28 14:25:12 drochner Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.112 2008/02/23 00:27:53 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.113 2008/02/28 14:25:12 drochner Exp $"); #include "opt_pci.h" @@ -895,6 +895,19 @@ pci_child_resume(device_t dv PMF_FN_ARGS) return true; } +static bool +pci_child_shutdown(device_t dv, int how) +{ + struct pci_child_power *priv = device_pmf_bus_private(dv); + pcireg_t csr; + + /* disable busmastering */ + csr = pci_conf_read(priv->p_pc, priv->p_tag, PCI_COMMAND_STATUS_REG); + csr &= ~PCI_COMMAND_MASTER_ENABLE; + pci_conf_write(priv->p_pc, priv->p_tag, PCI_COMMAND_STATUS_REG, csr); + return true; +} + static void pci_child_deregister(device_t dv) { @@ -933,7 +946,7 @@ pci_child_register(device_t child) } device_pmf_bus_register(child, priv, pci_child_suspend, - pci_child_resume, pci_child_deregister); + pci_child_resume, pci_child_shutdown, pci_child_deregister); return true; } diff --git a/sys/kern/kern_pmf.c b/sys/kern/kern_pmf.c index 2ec5ea0eac41..526d4d43c4ab 100644 --- a/sys/kern/kern_pmf.c +++ b/sys/kern/kern_pmf.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_pmf.c,v 1.12 2008/02/20 22:52:55 drochner Exp $ */ +/* $NetBSD: kern_pmf.c,v 1.13 2008/02/28 14:25:12 drochner Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill @@ -33,7 +33,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_pmf.c,v 1.12 2008/02/20 22:52:55 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_pmf.c,v 1.13 2008/02/28 14:25:12 drochner Exp $"); #include #include @@ -284,7 +284,7 @@ pmf_system_suspend(void) } void -pmf_system_shutdown(void) +pmf_system_shutdown(int how) { int depth, maxdepth; device_t curdev; @@ -308,11 +308,17 @@ pmf_system_shutdown(void) if (!device_pmf_is_registered(curdev)) continue; - if (!device_pmf_class_suspend(curdev)) { +#if 0 /* needed? */ + if (!device_pmf_class_shutdown(curdev, how)) { aprint_debug("(failed)"); continue; } - if (!device_pmf_driver_suspend(curdev)) { +#endif + if (!device_pmf_driver_shutdown(curdev, how)) { + aprint_debug("(failed)"); + continue; + } + if (!device_pmf_bus_shutdown(curdev, how)) { aprint_debug("(failed)"); continue; } @@ -348,10 +354,11 @@ pmf_get_platform(const char *key) } bool -pmf_device_register(device_t dev, - bool (*suspend)(device_t), bool (*resume)(device_t)) +pmf_device_register1(device_t dev, + bool (*suspend)(device_t), bool (*resume)(device_t), + bool (*shutdown)(device_t, int)) { - device_pmf_driver_register(dev, suspend, resume); + device_pmf_driver_register(dev, suspend, resume, shutdown); if (!device_pmf_driver_child_register(dev)) { device_pmf_driver_deregister(dev); diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index 0fd63cd177d3..00eca313be89 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_subr.c,v 1.181 2008/02/20 23:30:13 drochner Exp $ */ +/* $NetBSD: kern_subr.c,v 1.182 2008/02/28 14:25:12 drochner Exp $ */ /*- * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2006 The NetBSD Foundation, Inc. @@ -86,7 +86,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.181 2008/02/20 23:30:13 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.182 2008/02/28 14:25:12 drochner Exp $"); #include "opt_ddb.h" #include "opt_md.h" @@ -496,6 +496,8 @@ doshutdownhooks(void) free(dp, M_DEVBUF); #endif } + + pmf_system_shutdown(boothowto); } /* diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c index a59d8784a3bb..27d1f59828a1 100644 --- a/sys/kern/subr_autoconf.c +++ b/sys/kern/subr_autoconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.132 2008/02/27 19:59:05 matt Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.133 2008/02/28 14:25:12 drochner Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.132 2008/02/27 19:59:05 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.133 2008/02/28 14:25:12 drochner Exp $"); #include "opt_multiprocessor.h" #include "opt_ddb.h" @@ -1882,12 +1882,24 @@ device_pmf_driver_resume(device_t dev) return true; } +bool +device_pmf_driver_shutdown(device_t dev, int how) +{ + + if (*dev->dv_driver_shutdown != NULL && + !(*dev->dv_driver_shutdown)(dev, how)) + return false; + return true; +} + void device_pmf_driver_register(device_t dev, - bool (*suspend)(device_t), bool (*resume)(device_t)) + bool (*suspend)(device_t), bool (*resume)(device_t), + bool (*shutdown)(device_t, int)) { dev->dv_driver_suspend = suspend; dev->dv_driver_resume = resume; + dev->dv_driver_shutdown = shutdown; dev->dv_flags |= DVF_POWER_HANDLERS; } @@ -1951,14 +1963,25 @@ device_pmf_bus_resume(device_t dev) return true; } +bool +device_pmf_bus_shutdown(device_t dev, int how) +{ + + if (*dev->dv_bus_shutdown != NULL && + !(*dev->dv_bus_shutdown)(dev, how)) + return false; + return true; +} + void device_pmf_bus_register(device_t dev, void *priv, bool (*suspend)(device_t), bool (*resume)(device_t), - void (*deregister)(device_t)) + bool (*shutdown)(device_t, int), void (*deregister)(device_t)) { dev->dv_bus_private = priv; dev->dv_bus_resume = resume; dev->dv_bus_suspend = suspend; + dev->dv_bus_shutdown = shutdown; dev->dv_bus_deregister = deregister; } diff --git a/sys/sys/device.h b/sys/sys/device.h index ed8c57769d01..ca35f1351d6b 100644 --- a/sys/sys/device.h +++ b/sys/sys/device.h @@ -1,4 +1,4 @@ -/* $NetBSD: device.h,v 1.103 2008/02/12 17:30:59 joerg Exp $ */ +/* $NetBSD: device.h,v 1.104 2008/02/28 14:25:12 drochner Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -142,11 +142,13 @@ struct device { bool (*dv_driver_suspend)(device_t); bool (*dv_driver_resume)(device_t); + bool (*dv_driver_shutdown)(device_t, int); bool (*dv_driver_child_register)(device_t); void *dv_bus_private; bool (*dv_bus_suspend)(device_t); bool (*dv_bus_resume)(device_t); + bool (*dv_bus_shutdown)(device_t, int); void (*dv_bus_deregister)(device_t); void *dv_class_private; @@ -450,9 +452,11 @@ bool device_pmf_is_registered(device_t); bool device_pmf_driver_suspend(device_t); bool device_pmf_driver_resume(device_t); +bool device_pmf_driver_shutdown(device_t, int); void device_pmf_driver_register(device_t, - bool (*)(device_t), bool (*)(device_t)); + bool (*)(device_t), bool (*)(device_t), + bool (*)(device_t, int)); void device_pmf_driver_deregister(device_t); bool device_pmf_driver_child_register(device_t); @@ -462,9 +466,11 @@ void device_pmf_driver_set_child_register(device_t, void *device_pmf_bus_private(device_t); bool device_pmf_bus_suspend(device_t); bool device_pmf_bus_resume(device_t); +bool device_pmf_bus_shutdown(device_t, int); void device_pmf_bus_register(device_t, void *, bool (*)(device_t), bool (*)(device_t), + bool (*)(device_t, int), void (*)(device_t)); void device_pmf_bus_deregister(device_t); diff --git a/sys/sys/pmf.h b/sys/sys/pmf.h index 4bd2a5321dc8..21488b1f096d 100644 --- a/sys/sys/pmf.h +++ b/sys/sys/pmf.h @@ -1,4 +1,4 @@ -/* $NetBSD: pmf.h,v 1.6 2008/02/22 22:33:21 dyoung Exp $ */ +/* $NetBSD: pmf.h,v 1.7 2008/02/28 14:25:12 drochner Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill @@ -72,11 +72,15 @@ const char *pmf_get_platform(const char *); bool pmf_system_resume(void); bool pmf_system_bus_resume(void); bool pmf_system_suspend(void); -void pmf_system_shutdown(void); +void pmf_system_shutdown(int); -bool pmf_device_register(device_t, +bool pmf_device_register1(device_t, bool (*)(device_t), - bool (*)(device_t)); + bool (*)(device_t), + bool (*)(device_t, int)); +/* compatibility */ +#define pmf_device_register(d, s, r) pmf_device_register1((d), (s), (r), 0) + void pmf_device_deregister(device_t); bool pmf_device_suspend(device_t); bool pmf_device_resume(device_t);