endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
        }
 
+       /*
+        * Some buggy high speed devices have bulk endpoints using
+        * maxpacket sizes other than 512.  High speed HCDs may not
+        * be able to handle that particular bug, so let's warn...
+        */
+       if (to_usb_device(ddev)->speed == USB_SPEED_HIGH
+                       && usb_endpoint_xfer_bulk(d)) {
+               unsigned maxp;
+
+               maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize) & 0x07ff;
+               if (maxp != 512)
+                       dev_warn(ddev, "config %d interface %d altsetting %d "
+                               "bulk endpoint 0x%X has invalid maxpacket %d\n",
+                               cfgno, inum, asnum, d->bEndpointAddress,
+                               maxp);
+       }
+
        /* Skip over any Class Specific or Vendor Specific descriptors;
         * find the next endpoint or interface descriptor */
        endpoint->extra = buffer;
 
        type = usb_pipetype (urb->pipe);
        maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input);
 
+       /* 1024 byte maxpacket is a hardware ceiling.  High bandwidth
+        * acts like up to 3KB, but is built from smaller packets.
+        */
+       if (max_packet(maxp) > 1024) {
+               ehci_dbg(ehci, "bogus qh maxpacket %d\n", max_packet(maxp));
+               goto done;
+       }
+
        /* Compute interrupt scheduling parameters just once, and save.
         * - allowing for high bandwidth, how many nsec/uframe are used?
         * - split transactions need a second CSPLIT uframe; same question
                        info2 |= (EHCI_TUNE_MULT_HS << 30);
                } else if (type == PIPE_BULK) {
                        info1 |= (EHCI_TUNE_RL_HS << 28);
-                       info1 |= 512 << 16;     /* usb2 fixed maxpacket */
+                       /* The USB spec says that high speed bulk endpoints
+                        * always use 512 byte maxpacket.  But some device
+                        * vendors decided to ignore that, and MSFT is happy
+                        * to help them do so.  So now people expect to use
+                        * such nonconformant devices with Linux too; sigh.
+                        */
+                       info1 |= max_packet(maxp) << 16;
                        info2 |= (EHCI_TUNE_MULT_HS << 30);
                } else {                /* PIPE_INTERRUPT */
                        info1 |= max_packet (maxp) << 16;