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 <thomas.pugliese@xxxxxxxxx> diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index bdb0cc3..fe8bc77 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); -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html