tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: [drochner%netbsd.org@localhost: CVS commit: src/sys/kern]
M.Drochner%fz-juelich.de@localhost said:
> I've got some ideas how to seperate the shutdown functions from
> suspend while using the pmf structures for ordering. Please give me an
> hour to two to formulate this in C.
Ok it is straightforward, and has passed some testing.
Here is it, the "wd" shutdownhook is converted as an example.
My intention is mainly to allow the drivers to sort out
the actions needed for system suspend vs. shutdown, without
breaking API compatibility.
As a bonus, disabling DMA of PCI devices on shutdown is ensured,
whether the individual drivers care or not.
best regards
Matthias
(I'll be unavailable for the weekend, so take your time
to comment:-)
-------------------------------------------------------------------
-------------------------------------------------------------------
Forschungszentrum Juelich GmbH
52425 Juelich
Sitz der Gesellschaft: Juelich
Eingetragen im Handelsregister des Amtsgerichts Dueren Nr. HR B 3498
Vorsitzende des Aufsichtsrats: MinDir'in Baerbel Brumme-Bothe
Geschaeftsfuehrung: Prof. Dr. Achim Bachem (Vorsitzender),
Dr. Ulrich Krafft (stellv. Vorsitzender), Prof. Dr. Harald Bolt,
Dr. Sebastian M. Schmidt
-------------------------------------------------------------------
-------------------------------------------------------------------
#
# old_revision [08c89761b78a89cfe820ff73f0de234af2720548]
#
# patch "sys/dev/ata/wd.c"
# from [6bee0a76d876e0c20723f818be484c0675170b63]
# to [d9f7961e451ba27253e54baccb8bfe8283db2451]
#
# patch "sys/dev/ata/wdvar.h"
# from [0b8a56a70bba89fbdc6e61acba6cb4a440a157a8]
# to [2e28e22eec82cb32b11d597a98c11e857e7929ba]
#
# patch "sys/dev/pci/pci.c"
# from [21c8d60ef747b0027db8405f3d9012f9eda73b88]
# to [b2de66d581a6d1a2a431b6835b92c294f1583902]
#
# patch "sys/kern/kern_pmf.c"
# from [588065989f69c940a45cc9834ef626a11b87d594]
# to [52d14868f17de54af4a0b46726e8c45c447a27cd]
#
# patch "sys/kern/kern_subr.c"
# from [1bb7c6949a1a3715bf89614dd7bb79d4a0415c4b]
# to [470f6adcff74c6be3130fba5131233e369cc4b1e]
#
# patch "sys/kern/subr_autoconf.c"
# from [c12a649533928ec237fa70592d34cc86ac8e91fe]
# to [2b56f8546fd90d34724370d493d43592f18ec2b5]
#
# patch "sys/sys/device.h"
# from [9fa05caad7bd02c45d2005964ec7a0ae2ebe9b6c]
# to [6a1f524647cfc2671e4d81f829d795e0d545fef8]
#
# patch "sys/sys/pmf.h"
# from [74e5ca388e62c84e2b1d7b077ebaaf3b4de3bbb9]
# to [e610ac3c4191daf85afe0c91588af20fa9ba7c79]
#
============================================================
--- sys/dev/ata/wd.c 6bee0a76d876e0c20723f818be484c0675170b63
+++ sys/dev/ata/wd.c d9f7961e451ba27253e54baccb8bfe8283db2451
@@ -194,7 +194,7 @@ int wd_flushcache(struct wd_softc *, i
void wddone(void *);
int wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
int wd_flushcache(struct wd_softc *, int);
-void wd_shutdown(void *);
+bool wd_shutdown(device_t, int);
int wd_getcache(struct wd_softc *, int *);
int wd_setcache(struct wd_softc *, int);
@@ -417,10 +417,6 @@ wdattach(struct device *parent, struct d
disk_init(&wd->sc_dk, wd->sc_dev.dv_xname, &wddkdriver);
disk_attach(&wd->sc_dk);
wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;
- wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
- if (wd->sc_sdhook == NULL)
- aprint_error("%s: WARNING: unable to establish shutdown hook\n",
- wd->sc_dev.dv_xname);
#if NRND > 0
rnd_attach_source(&wd->rnd_source, wd->sc_dev.dv_xname,
RND_TYPE_DISK, 0);
@@ -429,7 +425,7 @@ wdattach(struct device *parent, struct d
/* Discover wedges on this disk. */
dkwedge_discover(&wd->sc_dk);
- if (!pmf_device_register(self, wd_suspend, NULL))
+ if (!pmf_device_register1(self, wd_suspend, NULL, wd_shutdown))
aprint_error_dev(self, "couldn't establish power handler\n");
}
@@ -505,10 +501,6 @@ wddetach(struct device *self, int flags)
sc->sc_bscount = 0;
#endif
- /* Get rid of the shutdown hook. */
- if (sc->sc_sdhook != NULL)
- shutdownhook_disestablish(sc->sc_sdhook);
-
pmf_device_deregister(self);
#if NRND > 0
@@ -1948,14 +1940,15 @@ wd_flushcache(struct wd_softc *wd, int f
return 0;
}
-void
-wd_shutdown(void *arg)
+bool
+wd_shutdown(device_t dev, int how)
{
- struct wd_softc *wd = arg;
+ struct wd_softc *wd = device_private(dev);
wd_flushcache(wd, AT_POLL);
- if ((boothowto & RB_POWERDOWN) == RB_POWERDOWN)
+ if ((how & RB_POWERDOWN) == RB_POWERDOWN)
wd_standby(wd, AT_POLL);
+ return true;
}
/*
============================================================
--- sys/dev/ata/wdvar.h 0b8a56a70bba89fbdc6e61acba6cb4a440a157a8
+++ sys/dev/ata/wdvar.h 2e28e22eec82cb32b11d597a98c11e857e7929ba
@@ -66,8 +66,6 @@ struct wd_softc {
int retries; /* number of xfer retry */
- void *sc_sdhook; /* our shutdown hook */
-
#ifdef WD_SOFTBADSECT
SLIST_HEAD(, disk_badsectors) sc_bslist;
u_int sc_bscount;
============================================================
--- sys/dev/pci/pci.c 21c8d60ef747b0027db8405f3d9012f9eda73b88
+++ sys/dev/pci/pci.c b2de66d581a6d1a2a431b6835b92c294f1583902
@@ -898,6 +898,19 @@ pci_child_resume(device_t dv)
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)
{
@@ -936,7 +949,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;
}
============================================================
--- sys/kern/kern_pmf.c 588065989f69c940a45cc9834ef626a11b87d594
+++ sys/kern/kern_pmf.c 52d14868f17de54af4a0b46726e8c45c447a27cd
@@ -284,7 +284,7 @@ void
}
void
-pmf_system_shutdown(void)
+pmf_system_shutdown(int how)
{
int depth, maxdepth;
device_t curdev;
@@ -308,14 +308,20 @@ 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 @@ bool
}
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);
============================================================
--- sys/kern/kern_subr.c 1bb7c6949a1a3715bf89614dd7bb79d4a0415c4b
+++ sys/kern/kern_subr.c 470f6adcff74c6be3130fba5131233e369cc4b1e
@@ -496,6 +496,8 @@ doshutdownhooks(void)
free(dp, M_DEVBUF);
#endif
}
+
+ pmf_system_shutdown(boothowto);
}
/*
============================================================
--- sys/kern/subr_autoconf.c c12a649533928ec237fa70592d34cc86ac8e91fe
+++ sys/kern/subr_autoconf.c 2b56f8546fd90d34724370d493d43592f18ec2b5
@@ -1876,12 +1876,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;
}
@@ -1945,14 +1957,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;
}
============================================================
--- sys/sys/device.h 9fa05caad7bd02c45d2005964ec7a0ae2ebe9b6c
+++ sys/sys/device.h 6a1f524647cfc2671e4d81f829d795e0d545fef8
@@ -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_driver_resume(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 @@ bool device_pmf_bus_resume(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);
============================================================
--- sys/sys/pmf.h 74e5ca388e62c84e2b1d7b077ebaaf3b4de3bbb9
+++ sys/sys/pmf.h e610ac3c4191daf85afe0c91588af20fa9ba7c79
@@ -68,11 +68,15 @@ bool pmf_system_suspend(void);
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);
Home |
Main Index |
Thread Index |
Old Index