Hi.  Patch below should fix a problem where USB stops working after
_second_ suspend/resume, which happens on various ThinkPad models.
Please test, and report both success stories and failures.  If nothing
comes up, I'll commit it in a week or so.

(Btw, has anyone encountered the problem on hardware other than ThinkPads?)


Index: sys/dev/acpi_support/acpi_ibm.c
===================================================================
--- sys/dev/acpi_support/acpi_ibm.c     (revision 267417)
+++ sys/dev/acpi_support/acpi_ibm.c     (working copy)
@@ -169,6 +169,9 @@ struct acpi_ibm_softc {
        int             light_get_supported;
        int             light_set_supported;
 
+       /* USB power workaround */
+       ACPI_HANDLE     power_handle;
+
        /* led(4) interface */
        struct cdev     *led_dev;
        int             led_busy;
@@ -365,6 +368,7 @@ acpi_ibm_attach(device_t dev)
 {
        struct acpi_ibm_softc   *sc;
        devclass_t              ec_devclass;
+       ACPI_STATUS             status;
 
        ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
 
@@ -448,6 +452,17 @@ acpi_ibm_attach(device_t dev)
        if (sc->light_set_supported)
                sc->led_dev = led_create_state(ibm_led, sc, "thinklight", 
sc->light_val);
 
+       /*
+        * Obtain a handle to the power resource available on many models.
+        * This must be turned on manually upon resume. Otherwise the system
+        * may, for instance, resume from S3 with usb(4) powered down.
+        */
+       status = AcpiGetHandle(sc->handle, "\\_SB.PCI0.LPC.EC.PUBS", 
&sc->power_handle);
+       if (ACPI_FAILURE(status)) {
+               device_printf(dev, "Failed to get power handle\n");
+               return (status);
+       }
+
        return (0);
 }
 
@@ -476,6 +491,7 @@ static int
 acpi_ibm_resume(device_t dev)
 {
        struct acpi_ibm_softc *sc = device_get_softc(dev);
+       ACPI_STATUS status;
 
        ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
 
@@ -495,6 +511,15 @@ acpi_ibm_resume(device_t dev)
 
                acpi_ibm_sysctl_set(sc, i, val);
        }
+       if (sc->power_handle != NULL) {
+               status = AcpiEvaluateObject(sc->power_handle,
+                   "_ON", NULL, NULL);
+               if (ACPI_FAILURE(status)) {
+                       device_printf(dev, "failed to switch %s on - %s\n",
+                           acpi_name(sc->power_handle),
+                           AcpiFormatException(status));
+               }
+       }
        ACPI_SERIAL_END(ibm);
 
        return (0);
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to