diff options
Diffstat (limited to 'drivers/usb/wusbcore/rh.c')
| -rw-r--r-- | drivers/usb/wusbcore/rh.c | 57 | 
1 files changed, 23 insertions, 34 deletions
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index a68ad7aa0b5..fe8bc777ab8 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -70,6 +70,7 @@   * wusbhc_rh_start_port_reset() ??? unimplemented   */  #include <linux/slab.h> +#include <linux/export.h>  #include "wusbhc.h"  /* @@ -133,30 +134,38 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)   *           big of a problem [and we can't make it an spinlock   *           because other parts need to take it and sleep] .   * - *           @usb_hcd is refcounted, so it won't dissapear under us + *           @usb_hcd is refcounted, so it won't disappear under us   *           and before killing a host, the polling of the root hub   *           would be stopped anyway.   */  int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf)  {  	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); -	size_t cnt, size; -	unsigned long *buf = (unsigned long *) _buf; +	size_t cnt, size, bits_set = 0;  	/* WE DON'T LOCK, see comment */ -	size = wusbhc->ports_max + 1 /* hub bit */; -	size = (size + 8 - 1) / 8;	/* round to bytes */ -	for (cnt = 0; cnt < wusbhc->ports_max; cnt++) -		if (wusb_port_by_idx(wusbhc, cnt)->change) -			set_bit(cnt + 1, buf); -		else -			clear_bit(cnt + 1, buf); -	return size; +	/* round up to bytes.  Hub bit is bit 0 so add 1. */ +	size = DIV_ROUND_UP(wusbhc->ports_max + 1, 8); + +	/* clear the output buffer. */ +	memset(_buf, 0, size); +	/* set the bit for each changed port. */ +	for (cnt = 0; cnt < wusbhc->ports_max; cnt++) { + +		if (wusb_port_by_idx(wusbhc, cnt)->change) { +			const int bitpos = cnt+1; + +			_buf[bitpos/8] |= (1 << (bitpos % 8)); +			bits_set++; +		} +	} + +	return bits_set ? size : 0;  }  EXPORT_SYMBOL_GPL(wusbhc_rh_status_data);  /* - * Return the hub's desciptor + * Return the hub's descriptor   *   * NOTE: almost cut and paste from ehci-hub.c   * @@ -184,8 +193,8 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue,  	descr->bPwrOn2PwrGood = 0;  	descr->bHubContrCurrent = 0;  	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */ -	memset(&descr->bitmap[0], 0, temp); -	memset(&descr->bitmap[temp], 0xff, temp); +	memset(&descr->u.hs.DeviceRemovable[0], 0, temp); +	memset(&descr->u.hs.DeviceRemovable[temp], 0xff, temp);  	return 0;  } @@ -392,26 +401,6 @@ int wusbhc_rh_control(struct usb_hcd *usb_hcd, u16 reqntype, u16 wValue,  }  EXPORT_SYMBOL_GPL(wusbhc_rh_control); -int wusbhc_rh_suspend(struct usb_hcd *usb_hcd) -{ -	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); -	dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__, -		usb_hcd, wusbhc); -	/* dump_stack(); */ -	return -ENOSYS; -} -EXPORT_SYMBOL_GPL(wusbhc_rh_suspend); - -int wusbhc_rh_resume(struct usb_hcd *usb_hcd) -{ -	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); -	dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__, -		usb_hcd, wusbhc); -	/* dump_stack(); */ -	return -ENOSYS; -} -EXPORT_SYMBOL_GPL(wusbhc_rh_resume); -  int wusbhc_rh_start_port_reset(struct usb_hcd *usb_hcd, unsigned port_idx)  {  	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);  | 
