From 467d296f47731bcba578cfdea8416b4c152c4f1b Mon Sep 17 00:00:00 2001 From: Thomas Pugliese Date: Thu, 8 Aug 2013 12:11:45 -0500 Subject: wusbcore: fix root hub hub_status_data to only return > 0 if status has actually changed The hub_status_data function on the wireless USB root hub controller (wusbhc_rh_status_data) always returns a positive value even if no ports have changed. This patch updates wusbhc_rh_status_data to only return a positive value if the root hub status needs to be queried. The current implementation can also leave the upper bits of the port bitmap uninitialized if wusbhc->ports_max is not one less than an even multiple of 8. This patch fixes that as well by initializing the buffer to 0. Signed-off-by: Thomas Pugliese Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/rh.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/usb/wusbcore') diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index bdb0cc3046b..fe8bc777ab8 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -141,18 +141,26 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx) 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); -- cgit v1.2.3