}
 
 /* USB 2.0 spec Section 11.24.4.5 */
-static int get_hub_descriptor(struct usb_device *hdev, void *data)
+static int get_hub_descriptor(struct usb_device *hdev,
+               struct usb_hub_descriptor *desc)
 {
        int i, ret, size;
        unsigned dtype;
        for (i = 0; i < 3; i++) {
                ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-                       dtype << 8, 0, data, size,
+                       dtype << 8, 0, desc, size,
                        USB_CTRL_GET_TIMEOUT);
                if (hub_is_superspeed(hdev)) {
                        if (ret == size)
                                return ret;
-               } else if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2)) {
+               } else if (ret >= USB_DT_HUB_NONVAR_SIZE + 2) {
+                       /* Make sure we have the DeviceRemovable field. */
+                       size = USB_DT_HUB_NONVAR_SIZE + desc->bNbrPorts / 8 + 1;
+                       if (ret < size)
+                               return -EMSGSIZE;
                        return ret;
                }
        }
        }
        mutex_init(&hub->status_mutex);
 
-       hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
+       hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
        if (!hub->descriptor) {
                ret = -ENOMEM;
                goto fail;