Re: Discussion about implementation of usb port power off mechanism for port with device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 23 Jul 2012, Lan Tianyu wrote:

> hi alan:
> 	I accord to your advice to implement usb port power off mechanism
> for port with device (add "auto" option for portX/control to allow port
> to be power off during device being suspended and power on when resuming).
> 
> 	http://marc.info/?l=linux-usb&m=133675841421390&w=2
> > I still don't see what the problem is.  They don't have to be
> > synchronized; all you need to do is make sure that the port's state
> > remains set to "off" until the debouncing is finished and you have
> > turned off the connect-change and enable-change features.
> 
> But the device is still disconnected after powering on the port during
> resuming. Caused by that port_power had been set to "on" when connect-change
> event was processed. My patch is at the bottom of the mail. If something
> wrong, please help me to correct. Thanks.


> @@ -3027,6 +3070,24 @@ int usb_port_resume(struct usb_device *u
>    	int		status;
>    	u16		portchange, portstatus;
> 
> +	if (hub->ports[port1 - 1]->port_power_policy == USB_PORT_POWER_AUTO
> +			&& hub->ports[port1 - 1]->power_state == USB_PORT_POWER_STATE_OFF) {
> +		set_port_feature(udev->parent, port1, USB_PORT_FEAT_POWER);
> +
> +		/*
> +		 * Wait for usb hub port to be reconnected in order to make
> +		 * the resume procedure successful.
> +		 */
> +		status = usb_port_wait_for_connected(hub, port1);
> +		if (status < 0) {
> +			dev_dbg(&udev->dev, "can't get reconnection after setting  port " \
> +				"power on, status %d\n", status);
> +			return status;
> +		}
> +		hub->ports[port1 - 1]->power_state = USB_PORT_POWER_STATE_ON;
> +		pr_info("%s: port%d connect state on %ld\n", __func__, port1, jiffies);
> +	}
> +
>    	/* Skip the initial Clear-Suspend step for a remote wakeup */
>    	status = hub_port_status(hub, port1, &portstatus, &portchange);
>    	if (status == 0 && !port_is_suspended(hub, portstatus))

A few lines later the driver does:

	set_bit(port1, hub->busy_bits);

You merely need to move this line up before the point where you turn
port power back on.  Make it the first executable line of the function.

> @@ -3058,7 +3119,6 @@ int usb_port_resume(struct usb_device *u
>    		 * sequence.
>    		 */
>    		status = hub_port_status(hub, port1, &portstatus, &portchange);
> -

You don't need to remove this blank line.

>    		/* TRSMRCY = 10 msec */
>    		msleep(10);
>    	}
> @@ -4177,6 +4237,13 @@ static void hub_port_connect_change(stru
>    		}
>    	}
> 
> +	if (hub->ports[port1 - 1]->port_power_policy == USB_PORT_POWER_AUTO
> +		&& hub->ports[port1 - 1]->power_state == USB_PORT_POWER_STATE_OFF) {

Does the policy matter here?  I suspect only the power_state is important.

> +		clear_bit(port1, hub->change_bits);
> +		return;
> +	}

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux