Add support for power mode filtering as some USB hardware does not support
power saving. Submitted by: Hans Petter Selasky
This commit is contained in:
parent
527aa7b226
commit
d2d71ce7a8
@ -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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1524,7 +1524,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
|
||||
* 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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -2133,12 +2133,39 @@ usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
|
@ -479,6 +479,7 @@ void usbd_set_parent_iface(struct usb_device *udev, uint8_t iface_index,
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user