diff options
-rw-r--r-- | drivers/usb/wusbcore/rh.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index bdb0cc3046b5..fe8bc777ab88 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) | |||
141 | int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf) | 141 | int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf) |
142 | { | 142 | { |
143 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); | 143 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); |
144 | size_t cnt, size; | 144 | size_t cnt, size, bits_set = 0; |
145 | unsigned long *buf = (unsigned long *) _buf; | ||
146 | 145 | ||
147 | /* WE DON'T LOCK, see comment */ | 146 | /* WE DON'T LOCK, see comment */ |
148 | size = wusbhc->ports_max + 1 /* hub bit */; | 147 | /* round up to bytes. Hub bit is bit 0 so add 1. */ |
149 | size = (size + 8 - 1) / 8; /* round to bytes */ | 148 | size = DIV_ROUND_UP(wusbhc->ports_max + 1, 8); |
150 | for (cnt = 0; cnt < wusbhc->ports_max; cnt++) | 149 | |
151 | if (wusb_port_by_idx(wusbhc, cnt)->change) | 150 | /* clear the output buffer. */ |
152 | set_bit(cnt + 1, buf); | 151 | memset(_buf, 0, size); |
153 | else | 152 | /* set the bit for each changed port. */ |
154 | clear_bit(cnt + 1, buf); | 153 | for (cnt = 0; cnt < wusbhc->ports_max; cnt++) { |
155 | return size; | 154 | |
155 | if (wusb_port_by_idx(wusbhc, cnt)->change) { | ||
156 | const int bitpos = cnt+1; | ||
157 | |||
158 | _buf[bitpos/8] |= (1 << (bitpos % 8)); | ||
159 | bits_set++; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | return bits_set ? size : 0; | ||
156 | } | 164 | } |
157 | EXPORT_SYMBOL_GPL(wusbhc_rh_status_data); | 165 | EXPORT_SYMBOL_GPL(wusbhc_rh_status_data); |
158 | 166 | ||