| .. | .. |
|---|
| 5 | 5 | * Released under the GPLv2 only. |
|---|
| 6 | 6 | */ |
|---|
| 7 | 7 | |
|---|
| 8 | +#include <linux/acpi.h> |
|---|
| 8 | 9 | #include <linux/pci.h> /* for scatterlist macros */ |
|---|
| 9 | 10 | #include <linux/usb.h> |
|---|
| 10 | 11 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 160 | 161 | return ret; |
|---|
| 161 | 162 | } |
|---|
| 162 | 163 | EXPORT_SYMBOL_GPL(usb_control_msg); |
|---|
| 164 | + |
|---|
| 165 | +/** |
|---|
| 166 | + * usb_control_msg_send - Builds a control "send" message, sends it off and waits for completion |
|---|
| 167 | + * @dev: pointer to the usb device to send the message to |
|---|
| 168 | + * @endpoint: endpoint to send the message to |
|---|
| 169 | + * @request: USB message request value |
|---|
| 170 | + * @requesttype: USB message request type value |
|---|
| 171 | + * @value: USB message value |
|---|
| 172 | + * @index: USB message index value |
|---|
| 173 | + * @driver_data: pointer to the data to send |
|---|
| 174 | + * @size: length in bytes of the data to send |
|---|
| 175 | + * @timeout: time in msecs to wait for the message to complete before timing |
|---|
| 176 | + * out (if 0 the wait is forever) |
|---|
| 177 | + * @memflags: the flags for memory allocation for buffers |
|---|
| 178 | + * |
|---|
| 179 | + * Context: !in_interrupt () |
|---|
| 180 | + * |
|---|
| 181 | + * This function sends a control message to a specified endpoint that is not |
|---|
| 182 | + * expected to fill in a response (i.e. a "send message") and waits for the |
|---|
| 183 | + * message to complete, or timeout. |
|---|
| 184 | + * |
|---|
| 185 | + * Do not use this function from within an interrupt context. If you need |
|---|
| 186 | + * an asynchronous message, or need to send a message from within interrupt |
|---|
| 187 | + * context, use usb_submit_urb(). If a thread in your driver uses this call, |
|---|
| 188 | + * make sure your disconnect() method can wait for it to complete. Since you |
|---|
| 189 | + * don't have a handle on the URB used, you can't cancel the request. |
|---|
| 190 | + * |
|---|
| 191 | + * The data pointer can be made to a reference on the stack, or anywhere else, |
|---|
| 192 | + * as it will not be modified at all. This does not have the restriction that |
|---|
| 193 | + * usb_control_msg() has where the data pointer must be to dynamically allocated |
|---|
| 194 | + * memory (i.e. memory that can be successfully DMAed to a device). |
|---|
| 195 | + * |
|---|
| 196 | + * Return: If successful, 0 is returned, Otherwise, a negative error number. |
|---|
| 197 | + */ |
|---|
| 198 | +int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request, |
|---|
| 199 | + __u8 requesttype, __u16 value, __u16 index, |
|---|
| 200 | + const void *driver_data, __u16 size, int timeout, |
|---|
| 201 | + gfp_t memflags) |
|---|
| 202 | +{ |
|---|
| 203 | + unsigned int pipe = usb_sndctrlpipe(dev, endpoint); |
|---|
| 204 | + int ret; |
|---|
| 205 | + u8 *data = NULL; |
|---|
| 206 | + |
|---|
| 207 | + if (usb_pipe_type_check(dev, pipe)) |
|---|
| 208 | + return -EINVAL; |
|---|
| 209 | + |
|---|
| 210 | + if (size) { |
|---|
| 211 | + data = kmemdup(driver_data, size, memflags); |
|---|
| 212 | + if (!data) |
|---|
| 213 | + return -ENOMEM; |
|---|
| 214 | + } |
|---|
| 215 | + |
|---|
| 216 | + ret = usb_control_msg(dev, pipe, request, requesttype, value, index, |
|---|
| 217 | + data, size, timeout); |
|---|
| 218 | + kfree(data); |
|---|
| 219 | + |
|---|
| 220 | + if (ret < 0) |
|---|
| 221 | + return ret; |
|---|
| 222 | + if (ret == size) |
|---|
| 223 | + return 0; |
|---|
| 224 | + return -EINVAL; |
|---|
| 225 | +} |
|---|
| 226 | +EXPORT_SYMBOL_GPL(usb_control_msg_send); |
|---|
| 227 | + |
|---|
| 228 | +/** |
|---|
| 229 | + * usb_control_msg_recv - Builds a control "receive" message, sends it off and waits for completion |
|---|
| 230 | + * @dev: pointer to the usb device to send the message to |
|---|
| 231 | + * @endpoint: endpoint to send the message to |
|---|
| 232 | + * @request: USB message request value |
|---|
| 233 | + * @requesttype: USB message request type value |
|---|
| 234 | + * @value: USB message value |
|---|
| 235 | + * @index: USB message index value |
|---|
| 236 | + * @driver_data: pointer to the data to be filled in by the message |
|---|
| 237 | + * @size: length in bytes of the data to be received |
|---|
| 238 | + * @timeout: time in msecs to wait for the message to complete before timing |
|---|
| 239 | + * out (if 0 the wait is forever) |
|---|
| 240 | + * @memflags: the flags for memory allocation for buffers |
|---|
| 241 | + * |
|---|
| 242 | + * Context: !in_interrupt () |
|---|
| 243 | + * |
|---|
| 244 | + * This function sends a control message to a specified endpoint that is |
|---|
| 245 | + * expected to fill in a response (i.e. a "receive message") and waits for the |
|---|
| 246 | + * message to complete, or timeout. |
|---|
| 247 | + * |
|---|
| 248 | + * Do not use this function from within an interrupt context. If you need |
|---|
| 249 | + * an asynchronous message, or need to send a message from within interrupt |
|---|
| 250 | + * context, use usb_submit_urb(). If a thread in your driver uses this call, |
|---|
| 251 | + * make sure your disconnect() method can wait for it to complete. Since you |
|---|
| 252 | + * don't have a handle on the URB used, you can't cancel the request. |
|---|
| 253 | + * |
|---|
| 254 | + * The data pointer can be made to a reference on the stack, or anywhere else |
|---|
| 255 | + * that can be successfully written to. This function does not have the |
|---|
| 256 | + * restriction that usb_control_msg() has where the data pointer must be to |
|---|
| 257 | + * dynamically allocated memory (i.e. memory that can be successfully DMAed to a |
|---|
| 258 | + * device). |
|---|
| 259 | + * |
|---|
| 260 | + * The "whole" message must be properly received from the device in order for |
|---|
| 261 | + * this function to be successful. If a device returns less than the expected |
|---|
| 262 | + * amount of data, then the function will fail. Do not use this for messages |
|---|
| 263 | + * where a variable amount of data might be returned. |
|---|
| 264 | + * |
|---|
| 265 | + * Return: If successful, 0 is returned, Otherwise, a negative error number. |
|---|
| 266 | + */ |
|---|
| 267 | +int usb_control_msg_recv(struct usb_device *dev, __u8 endpoint, __u8 request, |
|---|
| 268 | + __u8 requesttype, __u16 value, __u16 index, |
|---|
| 269 | + void *driver_data, __u16 size, int timeout, |
|---|
| 270 | + gfp_t memflags) |
|---|
| 271 | +{ |
|---|
| 272 | + unsigned int pipe = usb_rcvctrlpipe(dev, endpoint); |
|---|
| 273 | + int ret; |
|---|
| 274 | + u8 *data; |
|---|
| 275 | + |
|---|
| 276 | + if (!size || !driver_data || usb_pipe_type_check(dev, pipe)) |
|---|
| 277 | + return -EINVAL; |
|---|
| 278 | + |
|---|
| 279 | + data = kmalloc(size, memflags); |
|---|
| 280 | + if (!data) |
|---|
| 281 | + return -ENOMEM; |
|---|
| 282 | + |
|---|
| 283 | + ret = usb_control_msg(dev, pipe, request, requesttype, value, index, |
|---|
| 284 | + data, size, timeout); |
|---|
| 285 | + |
|---|
| 286 | + if (ret < 0) |
|---|
| 287 | + goto exit; |
|---|
| 288 | + |
|---|
| 289 | + if (ret == size) { |
|---|
| 290 | + memcpy(driver_data, data, size); |
|---|
| 291 | + ret = 0; |
|---|
| 292 | + } else { |
|---|
| 293 | + ret = -EINVAL; |
|---|
| 294 | + } |
|---|
| 295 | + |
|---|
| 296 | +exit: |
|---|
| 297 | + kfree(data); |
|---|
| 298 | + return ret; |
|---|
| 299 | +} |
|---|
| 300 | +EXPORT_SYMBOL_GPL(usb_control_msg_recv); |
|---|
| 163 | 301 | |
|---|
| 164 | 302 | /** |
|---|
| 165 | 303 | * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion |
|---|
| .. | .. |
|---|
| 647 | 785 | int i; |
|---|
| 648 | 786 | int result; |
|---|
| 649 | 787 | |
|---|
| 788 | + if (size <= 0) /* No point in asking for no data */ |
|---|
| 789 | + return -EINVAL; |
|---|
| 790 | + |
|---|
| 650 | 791 | memset(buf, 0, size); /* Make sure we parse really received data */ |
|---|
| 651 | 792 | |
|---|
| 652 | 793 | for (i = 0; i < 3; ++i) { |
|---|
| .. | .. |
|---|
| 694 | 835 | { |
|---|
| 695 | 836 | int i; |
|---|
| 696 | 837 | int result; |
|---|
| 838 | + |
|---|
| 839 | + if (size <= 0) /* No point in asking for no data */ |
|---|
| 840 | + return -EINVAL; |
|---|
| 697 | 841 | |
|---|
| 698 | 842 | for (i = 0; i < 3; ++i) { |
|---|
| 699 | 843 | /* retry on length 0 or stall; some devices are flakey */ |
|---|
| .. | .. |
|---|
| 947 | 1091 | if (dev->speed < USB_SPEED_SUPER) |
|---|
| 948 | 1092 | return 0; |
|---|
| 949 | 1093 | |
|---|
| 950 | | - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
|---|
| 1094 | + return usb_control_msg_send(dev, 0, |
|---|
| 951 | 1095 | USB_REQ_SET_ISOCH_DELAY, |
|---|
| 952 | 1096 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
|---|
| 953 | 1097 | dev->hub_delay, 0, NULL, 0, |
|---|
| 954 | | - USB_CTRL_SET_TIMEOUT); |
|---|
| 1098 | + USB_CTRL_SET_TIMEOUT, |
|---|
| 1099 | + GFP_NOIO); |
|---|
| 955 | 1100 | } |
|---|
| 956 | 1101 | |
|---|
| 957 | 1102 | /** |
|---|
| .. | .. |
|---|
| 1069 | 1214 | * (like some ibmcam model 1 units) seem to expect hosts to make |
|---|
| 1070 | 1215 | * this request for iso endpoints, which can't halt! |
|---|
| 1071 | 1216 | */ |
|---|
| 1072 | | - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
|---|
| 1073 | | - USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, |
|---|
| 1074 | | - USB_ENDPOINT_HALT, endp, NULL, 0, |
|---|
| 1075 | | - USB_CTRL_SET_TIMEOUT); |
|---|
| 1217 | + result = usb_control_msg_send(dev, 0, |
|---|
| 1218 | + USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, |
|---|
| 1219 | + USB_ENDPOINT_HALT, endp, NULL, 0, |
|---|
| 1220 | + USB_CTRL_SET_TIMEOUT, GFP_NOIO); |
|---|
| 1076 | 1221 | |
|---|
| 1077 | 1222 | /* don't un-halt or force to DATA0 except on success */ |
|---|
| 1078 | | - if (result < 0) |
|---|
| 1223 | + if (result) |
|---|
| 1079 | 1224 | return result; |
|---|
| 1080 | 1225 | |
|---|
| 1081 | 1226 | /* NOTE: seems like Microsoft and Apple don't bother verifying |
|---|
| .. | .. |
|---|
| 1244 | 1389 | */ |
|---|
| 1245 | 1390 | void usb_disable_device(struct usb_device *dev, int skip_ep0) |
|---|
| 1246 | 1391 | { |
|---|
| 1247 | | - int i, j; |
|---|
| 1248 | | - struct usb_hcd *hcd = bus_to_hcd(dev->bus); |
|---|
| 1392 | + int i; |
|---|
| 1249 | 1393 | |
|---|
| 1250 | 1394 | /* getting rid of interfaces will disconnect |
|---|
| 1251 | 1395 | * any drivers bound to them (a key side effect) |
|---|
| .. | .. |
|---|
| 1269 | 1413 | dev_dbg(&dev->dev, "unregistering interface %s\n", |
|---|
| 1270 | 1414 | dev_name(&interface->dev)); |
|---|
| 1271 | 1415 | remove_intf_ep_devs(interface); |
|---|
| 1272 | | - |
|---|
| 1273 | | - /* |
|---|
| 1274 | | - * Some special SoCs (e.g. rk322xh) USB 3.0 module |
|---|
| 1275 | | - * can't handle outstanding URBs by hardware when |
|---|
| 1276 | | - * when USB 3.0 device disconnect, so we need to |
|---|
| 1277 | | - * cancel all URBs pending on this device here. |
|---|
| 1278 | | - * |
|---|
| 1279 | | - * In addition, we just reuse the hub autosuspend |
|---|
| 1280 | | - * quirk but not add a new quirk for this issue. |
|---|
| 1281 | | - * Because it always occurs with autosuspend issue. |
|---|
| 1282 | | - */ |
|---|
| 1283 | | - if (hcd->self.root_hub->quirks & |
|---|
| 1284 | | - USB_QUIRK_AUTO_SUSPEND) { |
|---|
| 1285 | | - for (j = skip_ep0; j < 16; ++j) { |
|---|
| 1286 | | - usb_hcd_flush_endpoint(dev, |
|---|
| 1287 | | - dev->ep_out[j]); |
|---|
| 1288 | | - usb_hcd_flush_endpoint(dev, |
|---|
| 1289 | | - dev->ep_in[j]); |
|---|
| 1290 | | - } |
|---|
| 1291 | | - } |
|---|
| 1292 | | - |
|---|
| 1293 | 1416 | device_del(&interface->dev); |
|---|
| 1294 | 1417 | } |
|---|
| 1295 | 1418 | |
|---|
| .. | .. |
|---|
| 1459 | 1582 | if (dev->quirks & USB_QUIRK_NO_SET_INTF) |
|---|
| 1460 | 1583 | ret = -EPIPE; |
|---|
| 1461 | 1584 | else |
|---|
| 1462 | | - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
|---|
| 1463 | | - USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, |
|---|
| 1464 | | - alternate, interface, NULL, 0, 5000); |
|---|
| 1585 | + ret = usb_control_msg_send(dev, 0, |
|---|
| 1586 | + USB_REQ_SET_INTERFACE, |
|---|
| 1587 | + USB_RECIP_INTERFACE, alternate, |
|---|
| 1588 | + interface, NULL, 0, 5000, |
|---|
| 1589 | + GFP_NOIO); |
|---|
| 1465 | 1590 | |
|---|
| 1466 | 1591 | /* 9.4.10 says devices don't need this and are free to STALL the |
|---|
| 1467 | 1592 | * request if the interface only has one alternate setting. |
|---|
| .. | .. |
|---|
| 1471 | 1596 | "manual set_interface for iface %d, alt %d\n", |
|---|
| 1472 | 1597 | interface, alternate); |
|---|
| 1473 | 1598 | manual = 1; |
|---|
| 1474 | | - } else if (ret < 0) { |
|---|
| 1599 | + } else if (ret) { |
|---|
| 1475 | 1600 | /* Re-instate the old alt setting */ |
|---|
| 1476 | 1601 | usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting); |
|---|
| 1477 | 1602 | usb_enable_lpm(dev); |
|---|
| .. | .. |
|---|
| 1595 | 1720 | mutex_unlock(hcd->bandwidth_mutex); |
|---|
| 1596 | 1721 | return retval; |
|---|
| 1597 | 1722 | } |
|---|
| 1598 | | - retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
|---|
| 1599 | | - USB_REQ_SET_CONFIGURATION, 0, |
|---|
| 1600 | | - config->desc.bConfigurationValue, 0, |
|---|
| 1601 | | - NULL, 0, USB_CTRL_SET_TIMEOUT); |
|---|
| 1602 | | - if (retval < 0) { |
|---|
| 1723 | + retval = usb_control_msg_send(dev, 0, USB_REQ_SET_CONFIGURATION, 0, |
|---|
| 1724 | + config->desc.bConfigurationValue, 0, |
|---|
| 1725 | + NULL, 0, USB_CTRL_SET_TIMEOUT, |
|---|
| 1726 | + GFP_NOIO); |
|---|
| 1727 | + if (retval) { |
|---|
| 1603 | 1728 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); |
|---|
| 1604 | 1729 | usb_enable_lpm(dev); |
|---|
| 1605 | 1730 | mutex_unlock(hcd->bandwidth_mutex); |
|---|
| .. | .. |
|---|
| 1963 | 2088 | intf->dev.of_node = usb_of_get_interface_node(dev, |
|---|
| 1964 | 2089 | configuration, ifnum); |
|---|
| 1965 | 2090 | } |
|---|
| 2091 | + ACPI_COMPANION_SET(&intf->dev, ACPI_COMPANION(&dev->dev)); |
|---|
| 1966 | 2092 | intf->dev.driver = NULL; |
|---|
| 1967 | 2093 | intf->dev.bus = &usb_bus_type; |
|---|
| 1968 | 2094 | intf->dev.type = &usb_if_device_type; |
|---|
| 1969 | 2095 | intf->dev.groups = usb_interface_groups; |
|---|
| 1970 | | - /* |
|---|
| 1971 | | - * Please refer to usb_alloc_dev() to see why we set |
|---|
| 1972 | | - * dma_mask and dma_pfn_offset. |
|---|
| 1973 | | - */ |
|---|
| 1974 | | - intf->dev.dma_mask = dev->dev.dma_mask; |
|---|
| 1975 | | - intf->dev.dma_pfn_offset = dev->dev.dma_pfn_offset; |
|---|
| 1976 | 2096 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); |
|---|
| 1977 | 2097 | intf->minor = -1; |
|---|
| 1978 | 2098 | device_initialize(&intf->dev); |
|---|
| .. | .. |
|---|
| 1983 | 2103 | } |
|---|
| 1984 | 2104 | kfree(new_interfaces); |
|---|
| 1985 | 2105 | |
|---|
| 1986 | | - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
|---|
| 1987 | | - USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
|---|
| 1988 | | - NULL, 0, USB_CTRL_SET_TIMEOUT); |
|---|
| 1989 | | - if (ret < 0 && cp) { |
|---|
| 2106 | + ret = usb_control_msg_send(dev, 0, USB_REQ_SET_CONFIGURATION, 0, |
|---|
| 2107 | + configuration, 0, NULL, 0, |
|---|
| 2108 | + USB_CTRL_SET_TIMEOUT, GFP_NOIO); |
|---|
| 2109 | + if (ret && cp) { |
|---|
| 1990 | 2110 | /* |
|---|
| 1991 | 2111 | * All the old state is gone, so what else can we do? |
|---|
| 1992 | 2112 | * The device is probably useless now anyway. |
|---|
| .. | .. |
|---|
| 2030 | 2150 | for (i = 0; i < nintf; ++i) { |
|---|
| 2031 | 2151 | struct usb_interface *intf = cp->interface[i]; |
|---|
| 2032 | 2152 | |
|---|
| 2153 | + if (intf->dev.of_node && |
|---|
| 2154 | + !of_device_is_available(intf->dev.of_node)) { |
|---|
| 2155 | + dev_info(&dev->dev, "skipping disabled interface %d\n", |
|---|
| 2156 | + intf->cur_altsetting->desc.bInterfaceNumber); |
|---|
| 2157 | + continue; |
|---|
| 2158 | + } |
|---|
| 2159 | + |
|---|
| 2033 | 2160 | dev_dbg(&dev->dev, |
|---|
| 2034 | 2161 | "adding %s (config #%d, interface %d)\n", |
|---|
| 2035 | 2162 | dev_name(&intf->dev), configuration, |
|---|