Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Jun 2014 07:45:37 -0700
From:      Sean Bruno <sbruno@ignoranthack.me>
To:        Edward Tomasz =?iso-8859-2?Q?Napiera=B3a?= <trasz@FreeBSD.org>
Cc:        freebsd-current@FreeBSD.org
Subject:   Re: [patch] USB after second suspend/resume on ThinkPads.
Message-ID:  <1403016337.39699.0.camel@bruno>
In-Reply-To: <20140616192155.GE13481@brick.home>
References:  <20140616192155.GE13481@brick.home>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 2014-06-16 at 21:21 +0200, Edward Tomasz Napierała wrote:
> 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);
> ________________________________

T61 reporting in (even though this is the one you have).  It does indeed
work and I can access my USB ports after more than 2 suspend resumes.

sean




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1403016337.39699.0.camel>