diff options
| -rw-r--r-- | drivers/usb/core/config.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 24dfb33f90cb..a16c538d0132 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
| @@ -80,38 +80,18 @@ static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, | |||
| 80 | int max_tx; | 80 | int max_tx; |
| 81 | int i; | 81 | int i; |
| 82 | 82 | ||
| 83 | /* Allocate space for the SS endpoint companion descriptor */ | ||
| 84 | ep->ss_ep_comp = kzalloc(sizeof(struct usb_host_ss_ep_comp), | ||
| 85 | GFP_KERNEL); | ||
| 86 | if (!ep->ss_ep_comp) | ||
| 87 | return -ENOMEM; | ||
| 88 | desc = (struct usb_ss_ep_comp_descriptor *) buffer; | 83 | desc = (struct usb_ss_ep_comp_descriptor *) buffer; |
| 89 | if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) { | 84 | if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) { |
| 90 | dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " | 85 | dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " |
| 91 | " interface %d altsetting %d ep %d: " | 86 | " interface %d altsetting %d ep %d: " |
| 92 | "using minimum values\n", | 87 | "using minimum values\n", |
| 93 | cfgno, inum, asnum, ep->desc.bEndpointAddress); | 88 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
| 94 | ep->ss_ep_comp->desc.bLength = USB_DT_SS_EP_COMP_SIZE; | ||
| 95 | ep->ss_ep_comp->desc.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; | ||
| 96 | ep->ss_ep_comp->desc.bMaxBurst = 0; | ||
| 97 | /* | ||
| 98 | * Leave bmAttributes as zero, which will mean no streams for | ||
| 99 | * bulk, and isoc won't support multiple bursts of packets. | ||
| 100 | * With bursts of only one packet, and a Mult of 1, the max | ||
| 101 | * amount of data moved per endpoint service interval is one | ||
| 102 | * packet. | ||
| 103 | */ | ||
| 104 | if (usb_endpoint_xfer_isoc(&ep->desc) || | ||
| 105 | usb_endpoint_xfer_int(&ep->desc)) | ||
| 106 | ep->ss_ep_comp->desc.wBytesPerInterval = | ||
| 107 | ep->desc.wMaxPacketSize; | ||
| 108 | /* | 89 | /* |
| 109 | * The next descriptor is for an Endpoint or Interface, | 90 | * The next descriptor is for an Endpoint or Interface, |
| 110 | * no extra descriptors to copy into the companion structure, | 91 | * no extra descriptors to copy into the companion structure, |
| 111 | * and we didn't eat up any of the buffer. | 92 | * and we didn't eat up any of the buffer. |
| 112 | */ | 93 | */ |
| 113 | retval = 0; | 94 | return 0; |
| 114 | goto valid; | ||
| 115 | } | 95 | } |
| 116 | memcpy(&ep->ss_ep_comp->desc, desc, USB_DT_SS_EP_COMP_SIZE); | 96 | memcpy(&ep->ss_ep_comp->desc, desc, USB_DT_SS_EP_COMP_SIZE); |
| 117 | desc = &ep->ss_ep_comp->desc; | 97 | desc = &ep->ss_ep_comp->desc; |
| @@ -320,6 +300,28 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
| 320 | buffer += i; | 300 | buffer += i; |
| 321 | size -= i; | 301 | size -= i; |
| 322 | 302 | ||
| 303 | /* Allocate space for the SS endpoint companion descriptor */ | ||
| 304 | endpoint->ss_ep_comp = kzalloc(sizeof(struct usb_host_ss_ep_comp), | ||
| 305 | GFP_KERNEL); | ||
| 306 | if (!endpoint->ss_ep_comp) | ||
| 307 | return -ENOMEM; | ||
| 308 | |||
| 309 | /* Fill in some default values (may be overwritten later) */ | ||
| 310 | endpoint->ss_ep_comp->desc.bLength = USB_DT_SS_EP_COMP_SIZE; | ||
| 311 | endpoint->ss_ep_comp->desc.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; | ||
| 312 | endpoint->ss_ep_comp->desc.bMaxBurst = 0; | ||
| 313 | /* | ||
| 314 | * Leave bmAttributes as zero, which will mean no streams for | ||
| 315 | * bulk, and isoc won't support multiple bursts of packets. | ||
| 316 | * With bursts of only one packet, and a Mult of 1, the max | ||
| 317 | * amount of data moved per endpoint service interval is one | ||
| 318 | * packet. | ||
| 319 | */ | ||
| 320 | if (usb_endpoint_xfer_isoc(&endpoint->desc) || | ||
| 321 | usb_endpoint_xfer_int(&endpoint->desc)) | ||
| 322 | endpoint->ss_ep_comp->desc.wBytesPerInterval = | ||
| 323 | endpoint->desc.wMaxPacketSize; | ||
| 324 | |||
| 323 | if (size > 0) { | 325 | if (size > 0) { |
| 324 | retval = usb_parse_ss_endpoint_companion(ddev, cfgno, | 326 | retval = usb_parse_ss_endpoint_companion(ddev, cfgno, |
| 325 | inum, asnum, endpoint, num_ep, buffer, | 327 | inum, asnum, endpoint, num_ep, buffer, |
| @@ -329,6 +331,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
| 329 | retval = buffer - buffer0; | 331 | retval = buffer - buffer0; |
| 330 | } | 332 | } |
| 331 | } else { | 333 | } else { |
| 334 | dev_warn(ddev, "config %d interface %d altsetting %d " | ||
| 335 | "endpoint 0x%X has no " | ||
| 336 | "SuperSpeed companion descriptor\n", | ||
| 337 | cfgno, inum, asnum, d->bEndpointAddress); | ||
| 332 | retval = buffer - buffer0; | 338 | retval = buffer - buffer0; |
| 333 | } | 339 | } |
| 334 | } else { | 340 | } else { |
