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,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to