]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/wusbcore/rh.c
Merge branch 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[~andy/linux] / drivers / usb / wusbcore / rh.c
index bdb0cc3046b5f598d5e6540155bcfea4982bc0f1..fe8bc777ab887bd1bc51d132eae33c669dffe394 100644 (file)
@@ -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);