Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Nov 2010 01:49:22 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r215501 - stable/8/sys/dev/usb
Message-ID:  <201011190149.oAJ1nMZY053108@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: thompsa
Date: Fri Nov 19 01:49:22 2010
New Revision: 215501
URL: http://svn.freebsd.org/changeset/base/215501

Log:
  MFC r212135
  
   Add support for power mode filtering as some USB hardware does not support
   power saving.

Modified:
  stable/8/sys/dev/usb/usb_controller.h
  stable/8/sys/dev/usb/usb_device.c
  stable/8/sys/dev/usb/usb_generic.c
  stable/8/sys/dev/usb/usb_hub.c
  stable/8/sys/dev/usb/usbdi.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/usb/usb_controller.h
==============================================================================
--- stable/8/sys/dev/usb/usb_controller.h	Fri Nov 19 01:48:47 2010	(r215500)
+++ stable/8/sys/dev/usb/usb_controller.h	Fri Nov 19 01:49:22 2010	(r215501)
@@ -102,6 +102,10 @@ struct usb_bus_methods {
 	/* Optional transfer polling support */
 
 	void	(*xfer_poll) (struct usb_bus *);
+
+	/* Optional fixed power mode support */
+
+	void	(*get_power_mode) (struct usb_device *udev, int8_t *pmode);
 };
 
 /*

Modified: stable/8/sys/dev/usb/usb_device.c
==============================================================================
--- stable/8/sys/dev/usb/usb_device.c	Fri Nov 19 01:48:47 2010	(r215500)
+++ stable/8/sys/dev/usb/usb_device.c	Fri Nov 19 01:49:22 2010	(r215501)
@@ -1524,7 +1524,7 @@ usb_alloc_device(device_t parent_dev, st
 	 * of USB devices out there that do not work very well with
 	 * automatic suspend and resume!
 	 */
-	udev->power_mode = USB_POWER_MODE_ON;
+	udev->power_mode = usbd_filter_power_mode(udev, USB_POWER_MODE_ON);
 	udev->pwr_save.last_xfer_time = ticks;
 	/* we are not ready yet */
 	udev->refcount = 1;

Modified: stable/8/sys/dev/usb/usb_generic.c
==============================================================================
--- stable/8/sys/dev/usb/usb_generic.c	Fri Nov 19 01:48:47 2010	(r215500)
+++ stable/8/sys/dev/usb/usb_generic.c	Fri Nov 19 01:49:22 2010	(r215501)
@@ -1791,10 +1791,9 @@ ugen_get_power_mode(struct usb_fifo *f)
 {
 	struct usb_device *udev = f->udev;
 
-	if ((udev == NULL) ||
-	    (udev->parent_hub == NULL)) {
+	if (udev == NULL)
 		return (USB_POWER_MODE_ON);
-	}
+
 	return (udev->power_mode);
 }
 

Modified: stable/8/sys/dev/usb/usb_hub.c
==============================================================================
--- stable/8/sys/dev/usb/usb_hub.c	Fri Nov 19 01:48:47 2010	(r215500)
+++ stable/8/sys/dev/usb/usb_hub.c	Fri Nov 19 01:49:22 2010	(r215501)
@@ -2133,12 +2133,39 @@ usbd_set_power_mode(struct usb_device *u
 {
 	/* filter input argument */
 	if ((power_mode != USB_POWER_MODE_ON) &&
-	    (power_mode != USB_POWER_MODE_OFF)) {
+	    (power_mode != USB_POWER_MODE_OFF))
 		power_mode = USB_POWER_MODE_SAVE;
-	}
+
+	power_mode = usbd_filter_power_mode(udev, power_mode);	
+
 	udev->power_mode = power_mode;	/* update copy of power mode */
 
 #if USB_HAVE_POWERD
 	usb_bus_power_update(udev->bus);
 #endif
 }
+
+/*------------------------------------------------------------------------*
+ *	usbd_filter_power_mode
+ *
+ * This function filters the power mode based on hardware requirements.
+ *------------------------------------------------------------------------*/
+uint8_t
+usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode)
+{
+	struct usb_bus_methods *mtod;
+	int8_t temp;
+
+	mtod = udev->bus->methods;
+	temp = -1;
+
+	if (mtod->get_power_mode != NULL)
+		(mtod->get_power_mode) (udev, &temp);
+
+	/* check if we should not filter */
+	if (temp < 0)
+		return (power_mode);
+
+	/* use fixed power mode given by hardware driver */
+	return (temp);
+}

Modified: stable/8/sys/dev/usb/usbdi.h
==============================================================================
--- stable/8/sys/dev/usb/usbdi.h	Fri Nov 19 01:48:47 2010	(r215500)
+++ stable/8/sys/dev/usb/usbdi.h	Fri Nov 19 01:49:22 2010	(r215501)
@@ -479,6 +479,7 @@ void	usbd_set_parent_iface(struct usb_de
 uint8_t	usbd_get_bus_index(struct usb_device *udev);
 uint8_t	usbd_get_device_index(struct usb_device *udev);
 void	usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode);
+uint8_t	usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode);
 uint8_t	usbd_device_attached(struct usb_device *udev);
 
 void	usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen,



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