On Tuesday 19 April 2011 04:55 pm, Brandon Gooch wrote:
> On Tue, Apr 19, 2011 at 3:24 PM, Jung-uk Kim <j...@freebsd.org> 
wrote:
> > On Tuesday 19 April 2011 04:02 pm, Warner Losh wrote:
> >> Having chased boogiemen in this area before, I think this patch
> >> makes good sense even though it breaks the device model a
> >> little. However, the hardware in question really is special on
> >> x86...
> >>
> >> Warner
> >
> > Actually I was working on a similar patch and it should be ready
> > soon.
> >
> > Jung-uk Kim
>
> You have a willing (if not completely capable) tester here, so I
> always look forward to your patches.

:-)

http://people.freebsd.org/~jkim/syscons.diff

Also attached here.

> As the situation has greatly improved, I hesitate to even say this,
> but...I wish the USB stack could be made to be suspend/resume
> resilient. It's really the only problem child in my laptop.
> Fortunately, it's easy enough to build the USB stack as modules and
> unload/reload them.

I tried to do something about it but new USB stack is completely out 
of my expertise, unfortunately. :-(

Jung-uk Kim
Index: sys/isa/syscons_isa.c
===================================================================
--- sys/isa/syscons_isa.c       (revision 220864)
+++ sys/isa/syscons_isa.c       (working copy)
@@ -69,18 +69,7 @@ __FBSDID("$FreeBSD$");
 static devclass_t      sc_devclass;
 
 static sc_softc_t      main_softc;
-#ifdef SC_NO_SUSPEND_VTYSWITCH
-static int sc_no_suspend_vtswitch = 1;
-#else
-static int sc_no_suspend_vtswitch = 0;
-#endif
-static int sc_cur_scr;
 
-TUNABLE_INT("hw.syscons.sc_no_suspend_vtswitch", &sc_no_suspend_vtswitch);
-SYSCTL_DECL(_hw_syscons);
-SYSCTL_INT(_hw_syscons, OID_AUTO, sc_no_suspend_vtswitch, CTLFLAG_RW,
-    &sc_no_suspend_vtswitch, 0, "Disable VT switch before suspend.");
-
 static void
 scidentify(driver_t *driver, device_t parent)
 {
@@ -108,53 +97,6 @@ scattach(device_t dev)
            SC_AUTODETECT_KBD));
 }
 
-static int
-scsuspend(device_t dev)
-{
-       int             retry = 10;
-       sc_softc_t      *sc;
-
-       sc = &main_softc;
-
-       if (sc->cur_scp == NULL)
-               return (0);
-
-       if (sc->suspend_in_progress == 0) {
-               sc_cur_scr = sc->cur_scp->index;
-               if (!sc_no_suspend_vtswitch && sc_cur_scr != 0)
-                       do {
-                               sc_switch_scr(sc, 0);
-                               if (!sc->switch_in_progress)
-                                       break;
-                               pause("scsuspend", hz);
-                       } while (retry--);
-       }
-       sc->suspend_in_progress++;
-
-       return (0);
-}
-
-static int
-scresume(device_t dev)
-{
-       sc_softc_t      *sc;
-
-       sc = &main_softc;
-
-       if (sc->cur_scp == NULL)
-               return (0);
-
-       sc->suspend_in_progress--;
-       if (sc->suspend_in_progress == 0) {
-               if (!sc_no_suspend_vtswitch && sc_cur_scr != 0)
-                       sc_switch_scr(sc, sc_cur_scr);
-               else
-                       mark_all(sc->cur_scp);
-       }
-
-       return (0);
-}
-
 int
 sc_max_unit(void)
 {
@@ -300,8 +242,6 @@ static device_method_t sc_methods[] = {
        DEVMETHOD(device_identify,      scidentify),
        DEVMETHOD(device_probe,         scprobe),
        DEVMETHOD(device_attach,        scattach),
-       DEVMETHOD(device_suspend,       scsuspend),
-       DEVMETHOD(device_resume,        scresume),
        { 0, 0 }
 };
 
@@ -312,70 +252,3 @@ static driver_t sc_driver = {
 };
 
 DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
-
-static devclass_t      scpm_devclass;
-
-static void
-scpm_identify(driver_t *driver, device_t parent)
-{
-
-       device_add_child(parent, "scpm", 0);
-}
-
-static int
-scpm_probe(device_t dev)
-{
-
-       device_set_desc(dev, SC_DRIVER_NAME " suspend/resume");
-       device_quiet(dev);
-
-       return (BUS_PROBE_DEFAULT);
-}
-
-static int
-scpm_attach(device_t dev)
-{
-
-       bus_generic_probe(dev);
-       bus_generic_attach(dev);
-
-       return (0);
-}
-
-static int
-scpm_suspend(device_t dev)
-{
-       int error;
-
-       error = bus_generic_suspend(dev);
-       if (error != 0)
-               return (error);
-
-       return (scsuspend(dev));
-}
-
-static int
-scpm_resume(device_t dev)
-{
-
-       scresume(dev);
-
-       return (bus_generic_resume(dev));
-}
-
-static device_method_t scpm_methods[] = {
-       DEVMETHOD(device_identify,      scpm_identify),
-       DEVMETHOD(device_probe,         scpm_probe),
-       DEVMETHOD(device_attach,        scpm_attach),
-       DEVMETHOD(device_suspend,       scpm_suspend),
-       DEVMETHOD(device_resume,        scpm_resume),
-       { 0, 0 }
-};
-
-static driver_t scpm_driver = {
-       "scpm",
-       scpm_methods,
-       0
-};
-
-DRIVER_MODULE(scpm, vgapm, scpm_driver, scpm_devclass, 0, 0);
Index: sys/dev/syscons/syscons.c
===================================================================
--- sys/dev/syscons/syscons.c   (revision 220864)
+++ sys/dev/syscons/syscons.c   (working copy)
@@ -104,7 +104,8 @@ static      scr_stat        main_console;
 static struct tty      *main_devs[MAXCONS];
 
 static  char           init_done = COLD;
-static  char           shutdown_in_progress = FALSE;
+static int             shutdown_in_progress = FALSE;
+static int             suspend_in_progress = FALSE;
 static char            sc_malloc = FALSE;
 
 static int             saver_mode = CONS_NO_SAVER; /* LKM/user saver */
@@ -128,6 +129,13 @@ static     void            none_saver(sc_softc_t *sc, int 
blank)
 static void            (*current_saver)(sc_softc_t *, int) = none_saver;
 #endif
 
+#ifdef SC_NO_SUSPEND_VTYSWITCH
+static int             sc_no_suspend_vtswitch = 1;
+#else
+static int             sc_no_suspend_vtswitch = 0;
+#endif
+static int             sc_susp_scr;
+
 SYSCTL_NODE(_hw, OID_AUTO, syscons, CTLFLAG_RD, 0, "syscons");
 SYSCTL_NODE(_hw_syscons, OID_AUTO, saver, CTLFLAG_RD, 0, "saver");
 SYSCTL_INT(_hw_syscons_saver, OID_AUTO, keybonly, CTLFLAG_RW,
@@ -142,6 +150,9 @@ SYSCTL_INT(_hw_syscons, OID_AUTO, kbd_reboot, CTLF
 SYSCTL_INT(_hw_syscons, OID_AUTO, kbd_debug, CTLFLAG_RW|CTLFLAG_SECURE, 
&enable_kdbkey,
     0, "enable keyboard debug");
 #endif
+TUNABLE_INT("hw.syscons.sc_no_suspend_vtswitch", &sc_no_suspend_vtswitch);
+SYSCTL_INT(_hw_syscons, OID_AUTO, sc_no_suspend_vtswitch, CTLFLAG_RW,
+    &sc_no_suspend_vtswitch, 0, "Disable VT switch before suspend.");
 #if !defined(SC_NO_FONT_LOADING) && defined(SC_DFLT_FONT)
 #include "font.h"
 #endif
@@ -170,7 +181,9 @@ static kbd_callback_func_t sckbdevent;
 static void scinit(int unit, int flags);
 static scr_stat *sc_get_stat(struct tty *tp);
 static void scterm(int unit, int flags);
-static void scshutdown(void *arg, int howto);
+static void scshutdown(void *, int);
+static void scsuspend(void *);
+static void scresume(void *);
 static u_int scgetc(sc_softc_t *sc, u_int flags);
 #define SCGETC_CN      1
 #define SCGETC_NONBLOCK        2
@@ -518,10 +531,15 @@ sc_attach_unit(int unit, int flags)
        printf("\n");
     }
 
-    /* register a shutdown callback for the kernel console */
-    if (sc_console_unit == unit)
-       EVENTHANDLER_REGISTER(shutdown_pre_sync, scshutdown, 
-                             (void *)(uintptr_t)unit, SHUTDOWN_PRI_DEFAULT);
+    /* register suspend, resume and shutdown callbacks for the kernel console 
*/
+    if (sc_console_unit == unit) {
+       EVENTHANDLER_REGISTER(power_suspend, scsuspend, NULL,
+                             EVENTHANDLER_PRI_ANY);
+       EVENTHANDLER_REGISTER(power_resume, scresume, NULL,
+                             EVENTHANDLER_PRI_ANY);
+       EVENTHANDLER_REGISTER(shutdown_pre_sync, scshutdown, NULL,
+                             SHUTDOWN_PRI_DEFAULT);
+    }
 
     for (vc = 0; vc < sc->vtys; vc++) {
        if (sc->dev[vc] == NULL) {
@@ -1718,7 +1736,7 @@ sccnupdate(scr_stat *scp)
 {
     /* this is a cut-down version of scrn_timer()... */
 
-    if (scp->sc->suspend_in_progress || scp->sc->font_loading_in_progress)
+    if (suspend_in_progress || scp->sc->font_loading_in_progress)
        return;
 
     if (debugger > 0 || panicstr || shutdown_in_progress) {
@@ -1768,7 +1786,7 @@ scrn_timer(void *arg)
        return;
 
     /* don't do anything when we are performing some I/O operations */
-    if (sc->suspend_in_progress || sc->font_loading_in_progress) {
+    if (suspend_in_progress || sc->font_loading_in_progress) {
        if (again)
            timeout(scrn_timer, sc, hz / 10);
        return;
@@ -3007,18 +3025,66 @@ scterm(int unit, int flags)
 }
 
 static void
-scshutdown(void *arg, int howto)
+scshutdown(__unused void *arg, __unused int howto)
 {
-    /* assert(sc_console != NULL) */
 
-    sc_touch_scrn_saver();
-    if (!cold && sc_console
-       && sc_console->sc->cur_scp->smode.mode == VT_AUTO 
-       && sc_console->smode.mode == VT_AUTO)
-       sc_switch_scr(sc_console->sc, sc_console->index);
-    shutdown_in_progress = TRUE;
+       KASSERT(sc_console != NULL, ("sc_console != NULL"));
+       KASSERT(sc_console->sc != NULL, ("sc_console->sc != NULL"));
+       KASSERT(sc_console->sc->cur_scp != NULL,
+           ("sc_console->sc->cur_scp != NULL"));
+
+       sc_touch_scrn_saver();
+       if (!cold &&
+           sc_console->sc->cur_scp->index != sc_console->index &&
+           sc_console->sc->cur_scp->smode.mode == VT_AUTO &&
+           sc_console->smode.mode == VT_AUTO)
+               sc_switch_scr(sc_console->sc, sc_console->index);
+       shutdown_in_progress = TRUE;
 }
 
+static void
+scsuspend(__unused void *arg)
+{
+       int retry;
+
+       KASSERT(sc_console != NULL, ("sc_console != NULL"));
+       KASSERT(sc_console->sc != NULL, ("sc_console->sc != NULL"));
+       KASSERT(sc_console->sc->cur_scp != NULL,
+           ("sc_console->sc->cur_scp != NULL"));
+
+       sc_susp_scr = sc_console->sc->cur_scp->index;
+       if (sc_no_suspend_vtswitch ||
+           sc_susp_scr == sc_console->index) {
+               sc_touch_scrn_saver();
+               sc_susp_scr = -1;
+               return;
+       }
+       for (retry = 0; retry < 10; retry++) {
+               sc_switch_scr(sc_console->sc, sc_console->index);
+               if (!sc_console->sc->switch_in_progress)
+                       break;
+               pause("scsuspend", hz);
+       }
+       suspend_in_progress = TRUE;
+}
+
+static void
+scresume(__unused void *arg)
+{
+
+       KASSERT(sc_console != NULL, ("sc_console != NULL"));
+       KASSERT(sc_console->sc != NULL, ("sc_console->sc != NULL"));
+       KASSERT(sc_console->sc->cur_scp != NULL,
+           ("sc_console->sc->cur_scp != NULL"));
+
+       suspend_in_progress = FALSE;
+       if (sc_susp_scr < 0) {
+               mark_all(sc_console->sc->cur_scp);
+               return;
+       }
+       sc_switch_scr(sc_console->sc, sc_susp_scr);
+}
+
 int
 sc_clean_up(scr_stat *scp)
 {
Index: sys/dev/syscons/syscons.h
===================================================================
--- sys/dev/syscons/syscons.h   (revision 220864)
+++ sys/dev/syscons/syscons.h   (working copy)
@@ -230,7 +230,6 @@ typedef struct sc_softc {
        char            switch_in_progress;
        char            write_in_progress;
        char            blink_in_progress;
-       char            suspend_in_progress;
        struct mtx      video_mtx;
 
        long            scrn_time_stamp;
Index: sys/pc98/cbus/syscons_cbus.c
===================================================================
--- sys/pc98/cbus/syscons_cbus.c        (revision 220864)
+++ sys/pc98/cbus/syscons_cbus.c        (working copy)
@@ -49,18 +49,7 @@ __FBSDID("$FreeBSD$");
 static devclass_t      sc_devclass;
 
 static sc_softc_t      main_softc;
-#ifdef SC_NO_SUSPEND_VTYSWITCH
-static int sc_no_suspend_vtswitch = 1;
-#else
-static int sc_no_suspend_vtswitch = 0;
-#endif
-static int sc_cur_scr;
 
-TUNABLE_INT("hw.syscons.sc_no_suspend_vtswitch", &sc_no_suspend_vtswitch);
-SYSCTL_DECL(_hw_syscons);
-SYSCTL_INT(_hw_syscons, OID_AUTO, sc_no_suspend_vtswitch, CTLFLAG_RW,
-    &sc_no_suspend_vtswitch, 0, "Disable VT switch before suspend.");
-
 static void
 scidentify(driver_t *driver, device_t parent)
 {
@@ -87,47 +76,6 @@ scattach(device_t dev)
        return sc_attach_unit(device_get_unit(dev), device_get_flags(dev));
 }
 
-static int
-scsuspend(device_t dev)
-{
-       int             retry = 10;
-       sc_softc_t      *sc;
-
-       sc = &main_softc;
-
-       if (sc->cur_scp == NULL)
-               return (0);
-
-       sc_cur_scr = sc->cur_scp->index;
-
-       if (sc_no_suspend_vtswitch)
-               return (0);
-
-       do {
-               sc_switch_scr(sc, 0);
-               if (!sc->switch_in_progress) {
-                       break;
-               }
-               pause("scsuspend", hz);
-       } while (retry--);
-
-       return (0);
-}
-
-static int
-scresume(device_t dev)
-{
-       sc_softc_t      *sc;
-
-       if (sc_no_suspend_vtswitch)
-               return (0);
-
-       sc = &main_softc;
-       sc_switch_scr(sc, sc_cur_scr);
-
-       return (0);
-}
-
 int
 sc_max_unit(void)
 {
@@ -242,8 +190,6 @@ static device_method_t sc_methods[] = {
        DEVMETHOD(device_identify,      scidentify),
        DEVMETHOD(device_probe,         scprobe),
        DEVMETHOD(device_attach,        scattach),
-       DEVMETHOD(device_suspend,       scsuspend),
-       DEVMETHOD(device_resume,        scresume),
        { 0, 0 }
 };
 
_______________________________________________
freebsd-acpi@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
To unsubscribe, send any mail to "freebsd-acpi-unsubscr...@freebsd.org"

Reply via email to