Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'usb-6.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB / Thunderbolt driver fixes from Greg KH:
"Here are a small set of USB and Thunderbolt driver fixes for reported
problems and a documentation update, for 6.3-rc4.

Included in here are:

- documentation update for uvc gadget driver

- small thunderbolt driver fixes

- cdns3 driver fixes

- dwc3 driver fixes

- dwc2 driver fixes

- chipidea driver fixes

- typec driver fixes

- onboard_usb_hub device id updates

- quirk updates

All of these have been in linux-next with no reported problems"

* tag 'usb-6.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (30 commits)
usb: dwc2: fix a race, don't power off/on phy for dual-role mode
usb: dwc2: fix a devres leak in hw_enable upon suspend resume
usb: chipidea: core: fix possible concurrent when switch role
usb: chipdea: core: fix return -EINVAL if request role is the same with current role
thunderbolt: Rename shadowed variables bit to interrupt_bit and auto_clear_bit
thunderbolt: Disable interrupt auto clear for rings
thunderbolt: Use const qualifier for `ring_interrupt_index`
usb: gadget: Use correct endianness of the wLength field for WebUSB
uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2
usb: cdnsp: changes PCI Device ID to fix conflict with CNDS3 driver
usb: cdns3: Fix issue with using incorrect PCI device function
usb: cdnsp: Fixes issue with redundant Status Stage
MAINTAINERS: make me a reviewer of USB/IP
thunderbolt: Use scale field when allocating USB3 bandwidth
thunderbolt: Limit USB3 bandwidth of certain Intel USB4 host routers
thunderbolt: Call tb_check_quirks() after initializing adapters
thunderbolt: Add missing UNSET_INBOUND_SBTX for retimer access
thunderbolt: Fix memory leak in margining
usb: dwc2: drd: fix inconsistent mode if role-switch-default-mode="host"
docs: usb: Add documentation for the UVC Gadget
...

+625 -130
+352
Documentation/usb/gadget_uvc.rst
··· 1 + ======================= 2 + Linux UVC Gadget Driver 3 + ======================= 4 + 5 + Overview 6 + -------- 7 + The UVC Gadget driver is a driver for hardware on the *device* side of a USB 8 + connection. It is intended to run on a Linux system that has USB device-side 9 + hardware such as boards with an OTG port. 10 + 11 + On the device system, once the driver is bound it appears as a V4L2 device with 12 + the output capability. 13 + 14 + On the host side (once connected via USB cable), a device running the UVC Gadget 15 + driver *and controlled by an appropriate userspace program* should appear as a UVC 16 + specification compliant camera, and function appropriately with any program 17 + designed to handle them. The userspace program running on the device system can 18 + queue image buffers from a variety of sources to be transmitted via the USB 19 + connection. Typically this would mean forwarding the buffers from a camera sensor 20 + peripheral, but the source of the buffer is entirely dependent on the userspace 21 + companion program. 22 + 23 + Configuring the device kernel 24 + ----------------------------- 25 + The Kconfig options USB_CONFIGFS, USB_LIBCOMPOSITE, USB_CONFIGFS_F_UVC and 26 + USB_F_UVC must be selected to enable support for the UVC gadget. 27 + 28 + Configuring the gadget through configfs 29 + --------------------------------------- 30 + The UVC Gadget expects to be configured through configfs using the UVC function. 31 + This allows a significant degree of flexibility, as many of a UVC device's 32 + settings can be controlled this way. 33 + 34 + Not all of the available attributes are described here. For a complete enumeration 35 + see Documentation/ABI/testing/configfs-usb-gadget-uvc 36 + 37 + Assumptions 38 + ~~~~~~~~~~~ 39 + This section assumes that you have mounted configfs at `/sys/kernel/config` and 40 + created a gadget as `/sys/kernel/config/usb_gadget/g1`. 41 + 42 + The UVC Function 43 + ~~~~~~~~~~~~~~~~ 44 + 45 + The first step is to create the UVC function: 46 + 47 + .. code-block:: bash 48 + 49 + # These variables will be assumed throughout the rest of the document 50 + CONFIGFS="/sys/kernel/config" 51 + GADGET="$CONFIGFS/usb_gadget/g1" 52 + FUNCTION="$GADGET/functions/uvc.0" 53 + 54 + mkdir -p $FUNCTION 55 + 56 + Formats and Frames 57 + ~~~~~~~~~~~~~~~~~~ 58 + 59 + You must configure the gadget by telling it which formats you support, as well 60 + as the frame sizes and frame intervals that are supported for each format. In 61 + the current implementation there is no way for the gadget to refuse to set a 62 + format that the host instructs it to set, so it is important that this step is 63 + completed *accurately* to ensure that the host never asks for a format that 64 + can't be provided. 65 + 66 + Formats are created under the streaming/uncompressed and streaming/mjpeg configfs 67 + groups, with the framesizes created under the formats in the following 68 + structure: 69 + 70 + :: 71 + 72 + uvc.0 + 73 + | 74 + + streaming + 75 + | 76 + + mjpeg + 77 + | | 78 + | + mjpeg + 79 + | | 80 + | + 720p 81 + | | 82 + | + 1080p 83 + | 84 + + uncompressed + 85 + | 86 + + yuyv + 87 + | 88 + + 720p 89 + | 90 + + 1080p 91 + 92 + Each frame can then be configured with a width and height, plus the maximum 93 + buffer size required to store a single frame, and finally with the supported 94 + frame intervals for that format and framesize. Width and height are enumerated in 95 + units of pixels, frame interval in units of 100ns. To create the structure 96 + above with 2, 15 and 100 fps frameintervals for each framesize for example you 97 + might do: 98 + 99 + .. code-block:: bash 100 + 101 + create_frame() { 102 + # Example usage: 103 + # create_frame <width> <height> <group> <format name> 104 + 105 + WIDTH=$1 106 + HEIGHT=$2 107 + FORMAT=$3 108 + NAME=$4 109 + 110 + wdir=$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p 111 + 112 + mkdir -p $wdir 113 + echo $WIDTH > $wdir/wWidth 114 + echo $HEIGHT > $wdir/wHeight 115 + echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize 116 + cat <<EOF > $wdir/dwFrameInterval 117 + 666666 118 + 100000 119 + 5000000 120 + EOF 121 + } 122 + 123 + create_frame 1280 720 mjpeg mjpeg 124 + create_frame 1920 1080 mjpeg mjpeg 125 + create_frame 1280 720 uncompressed yuyv 126 + create_frame 1920 1080 uncompressed yuyv 127 + 128 + The only uncompressed format currently supported is YUYV, which is detailed at 129 + Documentation/userspace-api/media/v4l/pixfmt-packed.yuv.rst. 130 + 131 + Color Matching Descriptors 132 + ~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 + It's possible to specify some colometry information for each format you create. 134 + This step is optional, and default information will be included if this step is 135 + skipped; those default values follow those defined in the Color Matching Descriptor 136 + section of the UVC specification. 137 + 138 + To create a Color Matching Descriptor, create a configfs item and set its three 139 + attributes to your desired settings and then link to it from the format you wish 140 + it to be associated with: 141 + 142 + .. code-block:: bash 143 + 144 + # Create a new Color Matching Descriptor 145 + 146 + mkdir $FUNCTION/streaming/color_matching/yuyv 147 + pushd $FUNCTION/streaming/color_matching/yuyv 148 + 149 + echo 1 > bColorPrimaries 150 + echo 1 > bTransferCharacteristics 151 + echo 4 > bMatrixCoefficients 152 + 153 + popd 154 + 155 + # Create a symlink to the Color Matching Descriptor from the format's config item 156 + ln -s $FUNCTION/streaming/color_matching/yuyv $FUNCTION/streaming/uncompressed/yuyv 157 + 158 + For details about the valid values, consult the UVC specification. Note that a 159 + default color matching descriptor exists and is used by any format which does 160 + not have a link to a different Color Matching Descriptor. It's possible to 161 + change the attribute settings for the default descriptor, so bear in mind that if 162 + you do that you are altering the defaults for any format that does not link to 163 + a different one. 164 + 165 + 166 + Header linking 167 + ~~~~~~~~~~~~~~ 168 + 169 + The UVC specification requires that Format and Frame descriptors be preceded by 170 + Headers detailing things such as the number and cumulative size of the different 171 + Format descriptors that follow. This and similar operations are acheived in 172 + configfs by linking between the configfs item representing the header and the 173 + config items representing those other descriptors, in this manner: 174 + 175 + .. code-block:: bash 176 + 177 + mkdir $FUNCTION/streaming/header/h 178 + 179 + # This section links the format descriptors and their associated frames 180 + # to the header 181 + cd $FUNCTION/streaming/header/h 182 + ln -s ../../uncompressed/yuyv 183 + ln -s ../../mjpeg/mjpeg 184 + 185 + # This section ensures that the header will be transmitted for each 186 + # speed's set of descriptors. If support for a particular speed is not 187 + # needed then it can be skipped here. 188 + cd ../../class/fs 189 + ln -s ../../header/h 190 + cd ../../class/hs 191 + ln -s ../../header/h 192 + cd ../../class/ss 193 + ln -s ../../header/h 194 + cd ../../../control 195 + mkdir header/h 196 + ln -s header/h class/fs 197 + ln -s header/h class/ss 198 + 199 + 200 + Extension Unit Support 201 + ~~~~~~~~~~~~~~~~~~~~~~ 202 + 203 + A UVC Extension Unit (XU) basically provides a distinct unit to which control set 204 + and get requests can be addressed. The meaning of those control requests is 205 + entirely implementation dependent, but may be used to control settings outside 206 + of the UVC specification (for example enabling or disabling video effects). An 207 + XU can be inserted into the UVC unit chain or left free-hanging. 208 + 209 + Configuring an extension unit involves creating an entry in the appropriate 210 + directory and setting its attributes appropriately, like so: 211 + 212 + .. code-block:: bash 213 + 214 + mkdir $FUNCTION/control/extensions/xu.0 215 + pushd $FUNCTION/control/extensions/xu.0 216 + 217 + # Set the bUnitID of the Processing Unit as the source for this 218 + # Extension Unit 219 + echo 2 > baSourceID 220 + 221 + # Set this XU as the source of the default output terminal. This inserts 222 + # the XU into the UVC chain between the PU and OT such that the final 223 + # chain is IT > PU > XU.0 > OT 224 + cat bUnitID > ../../terminal/output/default/baSourceID 225 + 226 + # Flag some controls as being available for use. The bmControl field is 227 + # a bitmap with each bit denoting the availability of a particular 228 + # control. For example to flag the 0th, 2nd and 3rd controls available: 229 + echo 0x0d > bmControls 230 + 231 + # Set the GUID; this is a vendor-specific code identifying the XU. 232 + echo -e -n "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" > guidExtensionCode 233 + 234 + popd 235 + 236 + The bmControls attribute and the baSourceID attribute are multi-value attributes. 237 + This means that you may write multiple newline separated values to them. For 238 + example to flag the 1st, 2nd, 9th and 10th controls as being available you would 239 + need to write two values to bmControls, like so: 240 + 241 + .. code-block:: bash 242 + 243 + cat << EOF > bmControls 244 + 0x03 245 + 0x03 246 + EOF 247 + 248 + The multi-value nature of the baSourceID attribute belies the fact that XUs can 249 + be multiple-input, though note that this currently has no significant effect. 250 + 251 + The bControlSize attribute reflects the size of the bmControls attribute, and 252 + similarly bNrInPins reflects the size of the baSourceID attributes. Both 253 + attributes are automatically increased / decreased as you set bmControls and 254 + baSourceID. It is also possible to manually increase or decrease bControlSize 255 + which has the effect of truncating entries to the new size, or padding entries 256 + out with 0x00, for example: 257 + 258 + :: 259 + 260 + $ cat bmControls 261 + 0x03 262 + 0x05 263 + 264 + $ cat bControlSize 265 + 2 266 + 267 + $ echo 1 > bControlSize 268 + $ cat bmControls 269 + 0x03 270 + 271 + $ echo 2 > bControlSize 272 + $ cat bmControls 273 + 0x03 274 + 0x00 275 + 276 + bNrInPins and baSourceID function in the same way. 277 + 278 + Custom Strings Support 279 + ~~~~~~~~~~~~~~~~~~~~~~ 280 + 281 + String descriptors that provide a textual description for various parts of a 282 + USB device can be defined in the usual place within USB configfs, and may then 283 + be linked to from the UVC function root or from Extension Unit directories to 284 + assign those strings as descriptors: 285 + 286 + .. code-block:: bash 287 + 288 + # Create a string descriptor in us-EN and link to it from the function 289 + # root. The name of the link is significant here, as it declares this 290 + # descriptor to be intended for the Interface Association Descriptor. 291 + # Other significant link names at function root are vs0_desc and vs1_desc 292 + # For the VideoStreaming Interface 0/1 Descriptors. 293 + 294 + mkdir -p $GADGET/strings/0x409/iad_desc 295 + echo -n "Interface Associaton Descriptor" > $GADGET/strings/0x409/iad_desc/s 296 + ln -s $GADGET/strings/0x409/iad_desc $FUNCTION/iad_desc 297 + 298 + # Because the link to a String Descriptor from an Extension Unit clearly 299 + # associates the two, the name of this link is not significant and may 300 + # be set freely. 301 + 302 + mkdir -p $GADGET/strings/0x409/xu.0 303 + echo -n "A Very Useful Extension Unit" > $GADGET/strings/0x409/xu.0/s 304 + ln -s $GADGET/strings/0x409/xu.0 $FUNCTION/control/extensions/xu.0 305 + 306 + The interrupt endpoint 307 + ~~~~~~~~~~~~~~~~~~~~~~ 308 + 309 + The VideoControl interface has an optional interrupt endpoint which is by default 310 + disabled. This is intended to support delayed response control set requests for 311 + UVC (which should respond through the interrupt endpoint rather than tying up 312 + endpoint 0). At present support for sending data through this endpoint is missing 313 + and so it is left disabled to avoid confusion. If you wish to enable it you can 314 + do so through the configfs attribute: 315 + 316 + .. code-block:: bash 317 + 318 + echo 1 > $FUNCTION/control/enable_interrupt_ep 319 + 320 + Bandwidth configuration 321 + ~~~~~~~~~~~~~~~~~~~~~~~ 322 + 323 + There are three attributes which control the bandwidth of the USB connection. 324 + These live in the function root and can be set within limits: 325 + 326 + .. code-block:: bash 327 + 328 + # streaming_interval sets bInterval. Values range from 1..255 329 + echo 1 > $FUNCTION/streaming_interval 330 + 331 + # streaming_maxpacket sets wMaxPacketSize. Valid values are 1024/2048/3072 332 + echo 3072 > $FUNCTION/streaming_maxpacket 333 + 334 + # streaming_maxburst sets bMaxBurst. Valid values are 1..15 335 + echo 1 > $FUNCTION/streaming_maxburst 336 + 337 + 338 + The values passed here will be clamped to valid values according to the UVC 339 + specification (which depend on the speed of the USB connection). To understand 340 + how the settings influence bandwidth you should consult the UVC specifications, 341 + but a rule of thumb is that increasing the streaming_maxpacket setting will 342 + improve bandwidth (and thus the maximum possible framerate), whilst the same is 343 + true for streaming_maxburst provided the USB connection is running at SuperSpeed. 344 + Increasing streaming_interval will reduce bandwidth and framerate. 345 + 346 + The userspace application 347 + ------------------------- 348 + By itself, the UVC Gadget driver cannot do anything particularly interesting. It 349 + must be paired with a userspace program that responds to UVC control requests and 350 + fills buffers to be queued to the V4L2 device that the driver creates. How those 351 + things are achieved is implementation dependent and beyond the scope of this 352 + document, but a reference application can be found at https://gitlab.freedesktop.org/camera/uvc-gadget
+1
Documentation/usb/index.rst
··· 16 16 gadget_multi 17 17 gadget_printer 18 18 gadget_serial 19 + gadget_uvc 19 20 gadget-testing 20 21 iuu_phoenix 21 22 mass-storage
+1
MAINTAINERS
··· 21643 21643 M: Valentina Manea <valentina.manea.m@gmail.com> 21644 21644 M: Shuah Khan <shuah@kernel.org> 21645 21645 M: Shuah Khan <skhan@linuxfoundation.org> 21646 + R: Hongren Zheng <i@zenithal.me> 21646 21647 L: linux-usb@vger.kernel.org 21647 21648 S: Maintained 21648 21649 F: Documentation/usb/usbip_protocol.rst
+6 -6
drivers/thunderbolt/debugfs.c
··· 942 942 943 943 snprintf(dir_name, sizeof(dir_name), "port%d", port->port); 944 944 parent = debugfs_lookup(dir_name, port->sw->debugfs_dir); 945 - debugfs_remove_recursive(debugfs_lookup("margining", parent)); 945 + if (parent) 946 + debugfs_remove_recursive(debugfs_lookup("margining", parent)); 946 947 947 948 kfree(port->usb4->margining); 948 949 port->usb4->margining = NULL; ··· 968 967 969 968 static void margining_switch_remove(struct tb_switch *sw) 970 969 { 970 + struct tb_port *upstream, *downstream; 971 971 struct tb_switch *parent_sw; 972 - struct tb_port *downstream; 973 972 u64 route = tb_route(sw); 974 973 975 974 if (!route) 976 975 return; 977 976 978 - /* 979 - * Upstream is removed with the router itself but we need to 980 - * remove the downstream port margining directory. 981 - */ 977 + upstream = tb_upstream_port(sw); 982 978 parent_sw = tb_switch_parent(sw); 983 979 downstream = tb_port_at(route, parent_sw); 980 + 981 + margining_port_remove(upstream); 984 982 margining_port_remove(downstream); 985 983 } 986 984
+30 -19
drivers/thunderbolt/nhi.c
··· 46 46 #define QUIRK_AUTO_CLEAR_INT BIT(0) 47 47 #define QUIRK_E2E BIT(1) 48 48 49 - static int ring_interrupt_index(struct tb_ring *ring) 49 + static int ring_interrupt_index(const struct tb_ring *ring) 50 50 { 51 51 int bit = ring->hop; 52 52 if (!ring->is_tx) ··· 63 63 { 64 64 int reg = REG_RING_INTERRUPT_BASE + 65 65 ring_interrupt_index(ring) / 32 * 4; 66 - int bit = ring_interrupt_index(ring) & 31; 67 - int mask = 1 << bit; 66 + int interrupt_bit = ring_interrupt_index(ring) & 31; 67 + int mask = 1 << interrupt_bit; 68 68 u32 old, new; 69 69 70 70 if (ring->irq > 0) { 71 71 u32 step, shift, ivr, misc; 72 72 void __iomem *ivr_base; 73 + int auto_clear_bit; 73 74 int index; 74 75 75 76 if (ring->is_tx) ··· 78 77 else 79 78 index = ring->hop + ring->nhi->hop_count; 80 79 81 - if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) { 82 - /* 83 - * Ask the hardware to clear interrupt status 84 - * bits automatically since we already know 85 - * which interrupt was triggered. 86 - */ 87 - misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); 88 - if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) { 89 - misc |= REG_DMA_MISC_INT_AUTO_CLEAR; 90 - iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC); 91 - } 92 - } 80 + /* 81 + * Intel routers support a bit that isn't part of 82 + * the USB4 spec to ask the hardware to clear 83 + * interrupt status bits automatically since 84 + * we already know which interrupt was triggered. 85 + * 86 + * Other routers explicitly disable auto-clear 87 + * to prevent conditions that may occur where two 88 + * MSIX interrupts are simultaneously active and 89 + * reading the register clears both of them. 90 + */ 91 + misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); 92 + if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) 93 + auto_clear_bit = REG_DMA_MISC_INT_AUTO_CLEAR; 94 + else 95 + auto_clear_bit = REG_DMA_MISC_DISABLE_AUTO_CLEAR; 96 + if (!(misc & auto_clear_bit)) 97 + iowrite32(misc | auto_clear_bit, 98 + ring->nhi->iobase + REG_DMA_MISC); 93 99 94 100 ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE; 95 101 step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS; ··· 116 108 117 109 dev_dbg(&ring->nhi->pdev->dev, 118 110 "%s interrupt at register %#x bit %d (%#x -> %#x)\n", 119 - active ? "enabling" : "disabling", reg, bit, old, new); 111 + active ? "enabling" : "disabling", reg, interrupt_bit, old, new); 120 112 121 113 if (new == old) 122 114 dev_WARN(&ring->nhi->pdev->dev, ··· 401 393 402 394 static void ring_clear_msix(const struct tb_ring *ring) 403 395 { 396 + int bit; 397 + 404 398 if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) 405 399 return; 406 400 401 + bit = ring_interrupt_index(ring) & 31; 407 402 if (ring->is_tx) 408 - ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE); 403 + iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR); 409 404 else 410 - ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE + 411 - 4 * (ring->nhi->hop_count / 32)); 405 + iowrite32(BIT(bit), ring->nhi->iobase + REG_RING_INT_CLEAR + 406 + 4 * (ring->nhi->hop_count / 32)); 412 407 } 413 408 414 409 static irqreturn_t ring_msix(int irq, void *data)
+4 -2
drivers/thunderbolt/nhi_regs.h
··· 77 77 78 78 /* 79 79 * three bitfields: tx, rx, rx overflow 80 - * Every bitfield contains one bit for every hop (REG_HOP_COUNT). Registers are 81 - * cleared on read. New interrupts are fired only after ALL registers have been 80 + * Every bitfield contains one bit for every hop (REG_HOP_COUNT). 81 + * New interrupts are fired only after ALL registers have been 82 82 * read (even those containing only disabled rings). 83 83 */ 84 84 #define REG_RING_NOTIFY_BASE 0x37800 85 85 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32) 86 + #define REG_RING_INT_CLEAR 0x37808 86 87 87 88 /* 88 89 * two bitfields: rx, tx ··· 106 105 107 106 #define REG_DMA_MISC 0x39864 108 107 #define REG_DMA_MISC_INT_AUTO_CLEAR BIT(2) 108 + #define REG_DMA_MISC_DISABLE_AUTO_CLEAR BIT(17) 109 109 110 110 #define REG_INMAIL_DATA 0x39900 111 111
+44
drivers/thunderbolt/quirks.c
··· 20 20 } 21 21 } 22 22 23 + static void quirk_clx_disable(struct tb_switch *sw) 24 + { 25 + sw->quirks |= QUIRK_NO_CLX; 26 + tb_sw_dbg(sw, "disabling CL states\n"); 27 + } 28 + 29 + static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw) 30 + { 31 + struct tb_port *port; 32 + 33 + tb_switch_for_each_port(sw, port) { 34 + if (!tb_port_is_usb3_down(port)) 35 + continue; 36 + port->max_bw = 16376; 37 + tb_port_dbg(port, "USB3 maximum bandwidth limited to %u Mb/s\n", 38 + port->max_bw); 39 + } 40 + } 41 + 23 42 struct tb_quirk { 24 43 u16 hw_vendor_id; 25 44 u16 hw_device_id; ··· 56 37 * DP buffers. 57 38 */ 58 39 { 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation }, 40 + /* 41 + * Limit the maximum USB3 bandwidth for the following Intel USB4 42 + * host routers due to a hardware issue. 43 + */ 44 + { 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI0, 0x0000, 0x0000, 45 + quirk_usb3_maximum_bandwidth }, 46 + { 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI1, 0x0000, 0x0000, 47 + quirk_usb3_maximum_bandwidth }, 48 + { 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI0, 0x0000, 0x0000, 49 + quirk_usb3_maximum_bandwidth }, 50 + { 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI1, 0x0000, 0x0000, 51 + quirk_usb3_maximum_bandwidth }, 52 + { 0x8087, PCI_DEVICE_ID_INTEL_MTL_M_NHI0, 0x0000, 0x0000, 53 + quirk_usb3_maximum_bandwidth }, 54 + { 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI0, 0x0000, 0x0000, 55 + quirk_usb3_maximum_bandwidth }, 56 + { 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI1, 0x0000, 0x0000, 57 + quirk_usb3_maximum_bandwidth }, 58 + /* 59 + * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms. 60 + */ 61 + { 0x0438, 0x0208, 0x0000, 0x0000, quirk_clx_disable }, 62 + { 0x0438, 0x0209, 0x0000, 0x0000, quirk_clx_disable }, 63 + { 0x0438, 0x020a, 0x0000, 0x0000, quirk_clx_disable }, 64 + { 0x0438, 0x020b, 0x0000, 0x0000, quirk_clx_disable }, 59 65 }; 60 66 61 67 /**
+21 -2
drivers/thunderbolt/retimer.c
··· 187 187 return ret; 188 188 } 189 189 190 + static void tb_retimer_set_inbound_sbtx(struct tb_port *port) 191 + { 192 + int i; 193 + 194 + for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) 195 + usb4_port_retimer_set_inbound_sbtx(port, i); 196 + } 197 + 198 + static void tb_retimer_unset_inbound_sbtx(struct tb_port *port) 199 + { 200 + int i; 201 + 202 + for (i = TB_MAX_RETIMER_INDEX; i >= 1; i--) 203 + usb4_port_retimer_unset_inbound_sbtx(port, i); 204 + } 205 + 190 206 static ssize_t nvm_authenticate_store(struct device *dev, 191 207 struct device_attribute *attr, const char *buf, size_t count) 192 208 { ··· 229 213 rt->auth_status = 0; 230 214 231 215 if (val) { 216 + tb_retimer_set_inbound_sbtx(rt->port); 232 217 if (val == AUTHENTICATE_ONLY) { 233 218 ret = tb_retimer_nvm_authenticate(rt, true); 234 219 } else { ··· 249 232 } 250 233 251 234 exit_unlock: 235 + tb_retimer_unset_inbound_sbtx(rt->port); 252 236 mutex_unlock(&rt->tb->lock); 253 237 exit_rpm: 254 238 pm_runtime_mark_last_busy(&rt->dev); ··· 458 440 * Enable sideband channel for each retimer. We can do this 459 441 * regardless whether there is device connected or not. 460 442 */ 461 - for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) 462 - usb4_port_retimer_set_inbound_sbtx(port, i); 443 + tb_retimer_set_inbound_sbtx(port); 463 444 464 445 /* 465 446 * Before doing anything else, read the authentication status. ··· 480 463 else if (ret < 0) 481 464 break; 482 465 } 466 + 467 + tb_retimer_unset_inbound_sbtx(port); 483 468 484 469 if (!last_idx) 485 470 return 0;
+1
drivers/thunderbolt/sb_regs.h
··· 20 20 USB4_SB_OPCODE_ROUTER_OFFLINE = 0x4e45534c, /* "LSEN" */ 21 21 USB4_SB_OPCODE_ENUMERATE_RETIMERS = 0x4d554e45, /* "ENUM" */ 22 22 USB4_SB_OPCODE_SET_INBOUND_SBTX = 0x5055534c, /* "LSUP" */ 23 + USB4_SB_OPCODE_UNSET_INBOUND_SBTX = 0x50555355, /* "USUP" */ 23 24 USB4_SB_OPCODE_QUERY_LAST_RETIMER = 0x5453414c, /* "LAST" */ 24 25 USB4_SB_OPCODE_GET_NVM_SECTOR_SIZE = 0x53534e47, /* "GNSS" */ 25 26 USB4_SB_OPCODE_NVM_SET_OFFSET = 0x53504f42, /* "BOPS" */
+2 -2
drivers/thunderbolt/switch.c
··· 2968 2968 dev_warn(&sw->dev, "reading DROM failed: %d\n", ret); 2969 2969 tb_sw_dbg(sw, "uid: %#llx\n", sw->uid); 2970 2970 2971 - tb_check_quirks(sw); 2972 - 2973 2971 ret = tb_switch_set_uuid(sw); 2974 2972 if (ret) { 2975 2973 dev_err(&sw->dev, "failed to set UUID\n"); ··· 2985 2987 return ret; 2986 2988 } 2987 2989 } 2990 + 2991 + tb_check_quirks(sw); 2988 2992 2989 2993 tb_switch_default_link_ports(sw); 2990 2994
+12 -3
drivers/thunderbolt/tb.h
··· 23 23 #define NVM_MAX_SIZE SZ_512K 24 24 #define NVM_DATA_DWORDS 16 25 25 26 + /* Keep link controller awake during update */ 27 + #define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0) 28 + /* Disable CLx if not supported */ 29 + #define QUIRK_NO_CLX BIT(1) 30 + 26 31 /** 27 32 * struct tb_nvm - Structure holding NVM information 28 33 * @dev: Owner of the NVM ··· 272 267 * @group: Bandwidth allocation group the adapter is assigned to. Only 273 268 * used for DP IN adapters for now. 274 269 * @group_list: The adapter is linked to the group's list of ports through this 270 + * @max_bw: Maximum possible bandwidth through this adapter if set to 271 + * non-zero. 275 272 * 276 273 * In USB4 terminology this structure represents an adapter (protocol or 277 274 * lane adapter). ··· 301 294 unsigned int dma_credits; 302 295 struct tb_bandwidth_group *group; 303 296 struct list_head group_list; 297 + unsigned int max_bw; 304 298 }; 305 299 306 300 /** ··· 1027 1019 */ 1028 1020 static inline bool tb_switch_is_clx_supported(const struct tb_switch *sw) 1029 1021 { 1022 + if (sw->quirks & QUIRK_NO_CLX) 1023 + return false; 1024 + 1030 1025 return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw); 1031 1026 } 1032 1027 ··· 1245 1234 int usb4_port_sw_margin_errors(struct tb_port *port, u32 *errors); 1246 1235 1247 1236 int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index); 1237 + int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index); 1248 1238 int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf, 1249 1239 u8 size); 1250 1240 int usb4_port_retimer_write(struct tb_port *port, u8 index, u8 reg, ··· 1302 1290 struct usb4_port *usb4_port_device_add(struct tb_port *port); 1303 1291 void usb4_port_device_remove(struct usb4_port *usb4); 1304 1292 int usb4_port_device_resume(struct usb4_port *usb4); 1305 - 1306 - /* Keep link controller awake during update */ 1307 - #define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0) 1308 1293 1309 1294 void tb_check_quirks(struct tb_switch *sw); 1310 1295
+46 -7
drivers/thunderbolt/usb4.c
··· 1579 1579 } 1580 1580 1581 1581 /** 1582 + * usb4_port_retimer_unset_inbound_sbtx() - Disable sideband channel transactions 1583 + * @port: USB4 port 1584 + * @index: Retimer index 1585 + * 1586 + * Disables sideband channel transations on SBTX. The reverse of 1587 + * usb4_port_retimer_set_inbound_sbtx(). 1588 + */ 1589 + int usb4_port_retimer_unset_inbound_sbtx(struct tb_port *port, u8 index) 1590 + { 1591 + return usb4_port_retimer_op(port, index, 1592 + USB4_SB_OPCODE_UNSET_INBOUND_SBTX, 500); 1593 + } 1594 + 1595 + /** 1582 1596 * usb4_port_retimer_read() - Read from retimer sideband registers 1583 1597 * @port: USB4 port 1584 1598 * @index: Retimer index ··· 1882 1868 usb4_port_retimer_nvm_read_block, &info); 1883 1869 } 1884 1870 1871 + static inline unsigned int 1872 + usb4_usb3_port_max_bandwidth(const struct tb_port *port, unsigned int bw) 1873 + { 1874 + /* Take the possible bandwidth limitation into account */ 1875 + if (port->max_bw) 1876 + return min(bw, port->max_bw); 1877 + return bw; 1878 + } 1879 + 1885 1880 /** 1886 1881 * usb4_usb3_port_max_link_rate() - Maximum support USB3 link rate 1887 1882 * @port: USB3 adapter port ··· 1912 1889 return ret; 1913 1890 1914 1891 lr = (val & ADP_USB3_CS_4_MSLR_MASK) >> ADP_USB3_CS_4_MSLR_SHIFT; 1915 - return lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000; 1892 + ret = lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000; 1893 + 1894 + return usb4_usb3_port_max_bandwidth(port, ret); 1916 1895 } 1917 1896 1918 1897 /** ··· 1941 1916 return 0; 1942 1917 1943 1918 lr = val & ADP_USB3_CS_4_ALR_MASK; 1944 - return lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000; 1919 + ret = lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000; 1920 + 1921 + return usb4_usb3_port_max_bandwidth(port, ret); 1945 1922 } 1946 1923 1947 1924 static int usb4_usb3_port_cm_request(struct tb_port *port, bool request) ··· 2094 2067 int downstream_bw) 2095 2068 { 2096 2069 u32 val, ubw, dbw, scale; 2097 - int ret; 2070 + int ret, max_bw; 2098 2071 2099 - /* Read the used scale, hardware default is 0 */ 2100 - ret = tb_port_read(port, &scale, TB_CFG_PORT, 2101 - port->cap_adap + ADP_USB3_CS_3, 1); 2072 + /* Figure out suitable scale */ 2073 + scale = 0; 2074 + max_bw = max(upstream_bw, downstream_bw); 2075 + while (scale < 64) { 2076 + if (mbps_to_usb3_bw(max_bw, scale) < 4096) 2077 + break; 2078 + scale++; 2079 + } 2080 + 2081 + if (WARN_ON(scale >= 64)) 2082 + return -EINVAL; 2083 + 2084 + ret = tb_port_write(port, &scale, TB_CFG_PORT, 2085 + port->cap_adap + ADP_USB3_CS_3, 1); 2102 2086 if (ret) 2103 2087 return ret; 2104 2088 2105 - scale &= ADP_USB3_CS_3_SCALE_MASK; 2106 2089 ubw = mbps_to_usb3_bw(upstream_bw, scale); 2107 2090 dbw = mbps_to_usb3_bw(downstream_bw, scale); 2091 + 2092 + tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale); 2108 2093 2109 2094 ret = tb_port_read(port, &val, TB_CFG_PORT, 2110 2095 port->cap_adap + ADP_USB3_CS_2, 1);
+5
drivers/usb/cdns3/cdns3-pci-wrap.c
··· 60 60 return NULL; 61 61 } 62 62 63 + if (func->devfn != PCI_DEV_FN_HOST_DEVICE && 64 + func->devfn != PCI_DEV_FN_OTG) { 65 + return NULL; 66 + } 67 + 63 68 return func; 64 69 } 65 70
+1 -18
drivers/usb/cdns3/cdnsp-ep0.c
··· 403 403 case USB_REQ_SET_ISOCH_DELAY: 404 404 ret = cdnsp_ep0_set_isoch_delay(pdev, ctrl); 405 405 break; 406 - case USB_REQ_SET_INTERFACE: 407 - /* 408 - * Add request into pending list to block sending status stage 409 - * by libcomposite. 410 - */ 411 - list_add_tail(&pdev->ep0_preq.list, 412 - &pdev->ep0_preq.pep->pending_list); 413 - 414 - ret = cdnsp_ep0_delegate_req(pdev, ctrl); 415 - if (ret == -EBUSY) 416 - ret = 0; 417 - 418 - list_del(&pdev->ep0_preq.list); 419 - break; 420 406 default: 421 407 ret = cdnsp_ep0_delegate_req(pdev, ctrl); 422 408 break; ··· 460 474 else 461 475 ret = cdnsp_ep0_delegate_req(pdev, ctrl); 462 476 463 - if (!len) 464 - pdev->ep0_stage = CDNSP_STATUS_STAGE; 465 - 466 477 if (ret == USB_GADGET_DELAYED_STATUS) { 467 478 trace_cdnsp_ep0_status_stage("delayed"); 468 479 return; ··· 467 484 out: 468 485 if (ret < 0) 469 486 cdnsp_ep0_stall(pdev); 470 - else if (pdev->ep0_stage == CDNSP_STATUS_STAGE) 487 + else if (!len && pdev->ep0_stage != CDNSP_STATUS_STAGE) 471 488 cdnsp_status_stage(pdev); 472 489 }
+11 -16
drivers/usb/cdns3/cdnsp-pci.c
··· 29 29 #define PLAT_DRIVER_NAME "cdns-usbssp" 30 30 31 31 #define CDNS_VENDOR_ID 0x17cd 32 - #define CDNS_DEVICE_ID 0x0100 32 + #define CDNS_DEVICE_ID 0x0200 33 + #define CDNS_DRD_ID 0x0100 33 34 #define CDNS_DRD_IF (PCI_CLASS_SERIAL_USB << 8 | 0x80) 34 35 35 36 static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev) 36 37 { 37 - struct pci_dev *func; 38 - 39 38 /* 40 39 * Gets the second function. 41 - * It's little tricky, but this platform has two function. 42 - * The fist keeps resources for Host/Device while the second 43 - * keeps resources for DRD/OTG. 40 + * Platform has two function. The fist keeps resources for 41 + * Host/Device while the secon keeps resources for DRD/OTG. 44 42 */ 45 - func = pci_get_device(pdev->vendor, pdev->device, NULL); 46 - if (!func) 47 - return NULL; 43 + if (pdev->device == CDNS_DEVICE_ID) 44 + return pci_get_device(pdev->vendor, CDNS_DRD_ID, NULL); 45 + else if (pdev->device == CDNS_DRD_ID) 46 + return pci_get_device(pdev->vendor, CDNS_DEVICE_ID, NULL); 48 47 49 - if (func->devfn == pdev->devfn) { 50 - func = pci_get_device(pdev->vendor, pdev->device, func); 51 - if (!func) 52 - return NULL; 53 - } 54 - 55 - return func; 48 + return NULL; 56 49 } 57 50 58 51 static int cdnsp_pci_probe(struct pci_dev *pdev, ··· 222 229 { PCI_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 223 230 PCI_CLASS_SERIAL_USB_DEVICE, PCI_ANY_ID }, 224 231 { PCI_VENDOR_ID_CDNS, CDNS_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 232 + CDNS_DRD_IF, PCI_ANY_ID }, 233 + { PCI_VENDOR_ID_CDNS, CDNS_DRD_ID, PCI_ANY_ID, PCI_ANY_ID, 225 234 CDNS_DRD_IF, PCI_ANY_ID }, 226 235 { 0, } 227 236 };
+2
drivers/usb/chipidea/ci.h
··· 208 208 * @in_lpm: if the core in low power mode 209 209 * @wakeup_int: if wakeup interrupt occur 210 210 * @rev: The revision number for controller 211 + * @mutex: protect code from concorrent running when doing role switch 211 212 */ 212 213 struct ci_hdrc { 213 214 struct device *dev; ··· 261 260 bool in_lpm; 262 261 bool wakeup_int; 263 262 enum ci_revision rev; 263 + struct mutex mutex; 264 264 }; 265 265 266 266 static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
+10 -1
drivers/usb/chipidea/core.c
··· 984 984 strlen(ci->roles[role]->name))) 985 985 break; 986 986 987 - if (role == CI_ROLE_END || role == ci->role) 987 + if (role == CI_ROLE_END) 988 988 return -EINVAL; 989 + 990 + mutex_lock(&ci->mutex); 991 + 992 + if (role == ci->role) { 993 + mutex_unlock(&ci->mutex); 994 + return n; 995 + } 989 996 990 997 pm_runtime_get_sync(dev); 991 998 disable_irq(ci->irq); ··· 1002 995 ci_handle_vbus_change(ci); 1003 996 enable_irq(ci->irq); 1004 997 pm_runtime_put_sync(dev); 998 + mutex_unlock(&ci->mutex); 1005 999 1006 1000 return (ret == 0) ? n : ret; 1007 1001 } ··· 1038 1030 return -ENOMEM; 1039 1031 1040 1032 spin_lock_init(&ci->lock); 1033 + mutex_init(&ci->mutex); 1041 1034 ci->dev = dev; 1042 1035 ci->platdata = dev_get_platdata(dev); 1043 1036 ci->imx28_write_fix = !!(ci->platdata->flags &
+4 -1
drivers/usb/chipidea/otg.c
··· 167 167 168 168 void ci_handle_id_switch(struct ci_hdrc *ci) 169 169 { 170 - enum ci_role role = ci_otg_role(ci); 170 + enum ci_role role; 171 171 172 + mutex_lock(&ci->mutex); 173 + role = ci_otg_role(ci); 172 174 if (role != ci->role) { 173 175 dev_dbg(ci->dev, "switching from %s to %s\n", 174 176 ci_role(ci)->name, ci->roles[role]->name); ··· 200 198 if (role == CI_ROLE_GADGET) 201 199 ci_handle_vbus_change(ci); 202 200 } 201 + mutex_unlock(&ci->mutex); 203 202 } 204 203 /** 205 204 * ci_otg_work - perform otg (vbus/id) event handle
+2 -1
drivers/usb/dwc2/drd.c
··· 35 35 36 36 spin_unlock_irqrestore(&hsotg->lock, flags); 37 37 38 - dwc2_force_mode(hsotg, (hsotg->dr_mode == USB_DR_MODE_HOST)); 38 + dwc2_force_mode(hsotg, (hsotg->dr_mode == USB_DR_MODE_HOST) || 39 + (hsotg->role_sw_default_mode == USB_DR_MODE_HOST)); 39 40 } 40 41 41 42 static int dwc2_ovr_avalid(struct dwc2_hsotg *hsotg, bool valid)
+2 -4
drivers/usb/dwc2/gadget.c
··· 4549 4549 hsotg->gadget.dev.of_node = hsotg->dev->of_node; 4550 4550 hsotg->gadget.speed = USB_SPEED_UNKNOWN; 4551 4551 4552 - if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL || 4553 - (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) { 4552 + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { 4554 4553 ret = dwc2_lowlevel_hw_enable(hsotg); 4555 4554 if (ret) 4556 4555 goto err; ··· 4611 4612 if (!IS_ERR_OR_NULL(hsotg->uphy)) 4612 4613 otg_set_peripheral(hsotg->uphy->otg, NULL); 4613 4614 4614 - if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL || 4615 - (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) 4615 + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) 4616 4616 dwc2_lowlevel_hw_disable(hsotg); 4617 4617 4618 4618 return 0;
+3 -16
drivers/usb/dwc2/platform.c
··· 91 91 return 0; 92 92 } 93 93 94 - static void __dwc2_disable_regulators(void *data) 95 - { 96 - struct dwc2_hsotg *hsotg = data; 97 - 98 - regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); 99 - } 100 - 101 94 static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) 102 95 { 103 96 struct platform_device *pdev = to_platform_device(hsotg->dev); ··· 98 105 99 106 ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), 100 107 hsotg->supplies); 101 - if (ret) 102 - return ret; 103 - 104 - ret = devm_add_action_or_reset(&pdev->dev, 105 - __dwc2_disable_regulators, hsotg); 106 108 if (ret) 107 109 return ret; 108 110 ··· 156 168 if (hsotg->clk) 157 169 clk_disable_unprepare(hsotg->clk); 158 170 159 - return 0; 171 + return regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); 160 172 } 161 173 162 174 /** ··· 564 576 dwc2_debugfs_init(hsotg); 565 577 566 578 /* Gadget code manages lowlevel hw on its own */ 567 - if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL || 568 - (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) 579 + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) 569 580 dwc2_lowlevel_hw_disable(hsotg); 570 581 571 582 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ ··· 595 608 if (hsotg->params.activate_stm_id_vb_detection) 596 609 regulator_disable(hsotg->usb33d); 597 610 error: 598 - if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) 611 + if (hsotg->ll_hw_enabled) 599 612 dwc2_lowlevel_hw_disable(hsotg); 600 613 return retval; 601 614 }
+1 -1
drivers/usb/dwc3/core.h
··· 1098 1098 * change quirk. 1099 1099 * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate 1100 1100 * check during HS transmit. 1101 - * @resume-hs-terminations: Set if we enable quirk for fixing improper crc 1101 + * @resume_hs_terminations: Set if we enable quirk for fixing improper crc 1102 1102 * generation after resume from suspend. 1103 1103 * @parkmode_disable_ss_quirk: set if we need to disable all SuperSpeed 1104 1104 * instances in park mode.
+11 -3
drivers/usb/dwc3/gadget.c
··· 1699 1699 */ 1700 1700 static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) 1701 1701 { 1702 + struct dwc3 *dwc = dep->dwc; 1702 1703 struct dwc3_gadget_ep_cmd_params params; 1703 1704 u32 cmd; 1704 1705 int ret; ··· 1723 1722 WARN_ON_ONCE(ret); 1724 1723 dep->resource_index = 0; 1725 1724 1726 - if (!interrupt) 1725 + if (!interrupt) { 1726 + if (!DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC3, 310A)) 1727 + mdelay(1); 1727 1728 dep->flags &= ~DWC3_EP_TRANSFER_STARTED; 1728 - else if (!ret) 1729 + } else if (!ret) { 1729 1730 dep->flags |= DWC3_EP_END_TRANSFER_PENDING; 1731 + } 1730 1732 1731 1733 dep->flags &= ~DWC3_EP_DELAY_STOP; 1732 1734 return ret; ··· 3778 3774 * enabled, the EndTransfer command will have completed upon 3779 3775 * returning from this function. 3780 3776 * 3781 - * This mode is NOT available on the DWC_usb31 IP. 3777 + * This mode is NOT available on the DWC_usb31 IP. In this 3778 + * case, if the IOC bit is not set, then delay by 1ms 3779 + * after issuing the EndTransfer command. This allows for the 3780 + * controller to handle the command completely before DWC3 3781 + * remove requests attempts to unmap USB request buffers. 3782 3782 */ 3783 3783 3784 3784 __dwc3_stop_active_transfer(dep, force, interrupt);
+3 -4
drivers/usb/gadget/composite.c
··· 2079 2079 sizeof(url_descriptor->URL) 2080 2080 - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_offset); 2081 2081 2082 - if (ctrl->wLength < WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH 2083 - + landing_page_length) 2084 - landing_page_length = ctrl->wLength 2085 - - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_offset; 2082 + if (w_length < WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_length) 2083 + landing_page_length = w_length 2084 + - WEBUSB_URL_DESCRIPTOR_HEADER_LENGTH + landing_page_offset; 2086 2085 2087 2086 memcpy(url_descriptor->URL, 2088 2087 cdev->landing_page + landing_page_offset,
+1 -1
drivers/usb/gadget/function/u_audio.c
··· 1422 1422 uac = g_audio->uac; 1423 1423 card = uac->card; 1424 1424 if (card) 1425 - snd_card_free(card); 1425 + snd_card_free_when_closed(card); 1426 1426 1427 1427 kfree(uac->p_prm.reqs); 1428 1428 kfree(uac->c_prm.reqs);
+1
drivers/usb/misc/onboard_usb_hub.c
··· 410 410 { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */ 411 411 { USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 */ 412 412 { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */ 413 + { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 */ 413 414 { USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */ 414 415 { USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 */ 415 416 { USB_DEVICE(VENDOR_ID_REALTEK, 0x0414) }, /* RTS5414 USB 3.2 */
+1
drivers/usb/misc/onboard_usb_hub.h
··· 36 36 37 37 static const struct of_device_id onboard_hub_match[] = { 38 38 { .compatible = "usb424,2514", .data = &microchip_usb424_data, }, 39 + { .compatible = "usb424,2517", .data = &microchip_usb424_data, }, 39 40 { .compatible = "usb451,8140", .data = &ti_tusb8041_data, }, 40 41 { .compatible = "usb451,8142", .data = &ti_tusb8041_data, }, 41 42 { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, },
+7
drivers/usb/storage/unusual_uas.h
··· 111 111 USB_SC_DEVICE, USB_PR_DEVICE, NULL, 112 112 US_FL_BROKEN_FUA), 113 113 114 + /* Reported by: Yaroslav Furman <yaro330@gmail.com> */ 115 + UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x9999, 116 + "JMicron", 117 + "JMS583Gen 2", 118 + USB_SC_DEVICE, USB_PR_DEVICE, NULL, 119 + US_FL_NO_REPORT_OPCODES), 120 + 114 121 /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ 115 122 UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, 116 123 "PNY",
+24 -4
drivers/usb/typec/tcpm/tcpm.c
··· 1445 1445 static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, 1446 1446 const u32 *data, int cnt) 1447 1447 { 1448 + u32 vdo_hdr = port->vdo_data[0]; 1449 + 1448 1450 WARN_ON(!mutex_is_locked(&port->lock)); 1449 1451 1450 - /* Make sure we are not still processing a previous VDM packet */ 1451 - WARN_ON(port->vdm_state > VDM_STATE_DONE); 1452 + /* If is sending discover_identity, handle received message first */ 1453 + if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMD(vdo_hdr) == CMD_DISCOVER_IDENT) { 1454 + port->send_discover = true; 1455 + mod_send_discover_delayed_work(port, SEND_DISCOVER_RETRY_MS); 1456 + } else { 1457 + /* Make sure we are not still processing a previous VDM packet */ 1458 + WARN_ON(port->vdm_state > VDM_STATE_DONE); 1459 + } 1452 1460 1453 1461 port->vdo_count = cnt + 1; 1454 1462 port->vdo_data[0] = header; ··· 1956 1948 switch (PD_VDO_CMD(vdo_hdr)) { 1957 1949 case CMD_DISCOVER_IDENT: 1958 1950 res = tcpm_ams_start(port, DISCOVER_IDENTITY); 1959 - if (res == 0) 1951 + if (res == 0) { 1960 1952 port->send_discover = false; 1961 - else if (res == -EAGAIN) 1953 + } else if (res == -EAGAIN) { 1954 + port->vdo_data[0] = 0; 1962 1955 mod_send_discover_delayed_work(port, 1963 1956 SEND_DISCOVER_RETRY_MS); 1957 + } 1964 1958 break; 1965 1959 case CMD_DISCOVER_SVID: 1966 1960 res = tcpm_ams_start(port, DISCOVER_SVIDS); ··· 2045 2035 unsigned long timeout; 2046 2036 2047 2037 port->vdm_retries = 0; 2038 + port->vdo_data[0] = 0; 2048 2039 port->vdm_state = VDM_STATE_BUSY; 2049 2040 timeout = vdm_ready_timeout(vdo_hdr); 2050 2041 mod_vdm_delayed_work(port, timeout); ··· 4581 4570 case SOFT_RESET: 4582 4571 port->message_id = 0; 4583 4572 port->rx_msgid = -1; 4573 + /* remove existing capabilities */ 4574 + usb_power_delivery_unregister_capabilities(port->partner_source_caps); 4575 + port->partner_source_caps = NULL; 4584 4576 tcpm_pd_send_control(port, PD_CTRL_ACCEPT); 4585 4577 tcpm_ams_finish(port); 4586 4578 if (port->pwr_role == TYPEC_SOURCE) { ··· 4603 4589 case SOFT_RESET_SEND: 4604 4590 port->message_id = 0; 4605 4591 port->rx_msgid = -1; 4592 + /* remove existing capabilities */ 4593 + usb_power_delivery_unregister_capabilities(port->partner_source_caps); 4594 + port->partner_source_caps = NULL; 4606 4595 if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET)) 4607 4596 tcpm_set_state_cond(port, hard_reset_state(port), 0); 4608 4597 else ··· 4735 4718 tcpm_set_state(port, SNK_STARTUP, 0); 4736 4719 break; 4737 4720 case PR_SWAP_SNK_SRC_SINK_OFF: 4721 + /* will be source, remove existing capabilities */ 4722 + usb_power_delivery_unregister_capabilities(port->partner_source_caps); 4723 + port->partner_source_caps = NULL; 4738 4724 /* 4739 4725 * Prevent vbus discharge circuit from turning on during PR_SWAP 4740 4726 * as this is not a disconnect.
+15 -18
drivers/usb/typec/ucsi/ucsi.c
··· 1125 1125 return NULL; 1126 1126 } 1127 1127 1128 - static int ucsi_register_port(struct ucsi *ucsi, int index) 1128 + static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) 1129 1129 { 1130 1130 struct usb_power_delivery_desc desc = { ucsi->cap.pd_version}; 1131 1131 struct usb_power_delivery_capabilities_desc pd_caps; 1132 1132 struct usb_power_delivery_capabilities *pd_cap; 1133 - struct ucsi_connector *con = &ucsi->connector[index]; 1134 1133 struct typec_capability *cap = &con->typec_cap; 1135 1134 enum typec_accessory *accessory = cap->accessory; 1136 1135 enum usb_role u_role = USB_ROLE_NONE; ··· 1150 1151 init_completion(&con->complete); 1151 1152 mutex_init(&con->lock); 1152 1153 INIT_LIST_HEAD(&con->partner_tasks); 1153 - con->num = index + 1; 1154 1154 con->ucsi = ucsi; 1155 1155 1156 1156 cap->fwnode = ucsi_find_fwnode(con); ··· 1326 1328 */ 1327 1329 static int ucsi_init(struct ucsi *ucsi) 1328 1330 { 1329 - struct ucsi_connector *con; 1330 - u64 command; 1331 + struct ucsi_connector *con, *connector; 1332 + u64 command, ntfy; 1331 1333 int ret; 1332 1334 int i; 1333 1335 ··· 1339 1341 } 1340 1342 1341 1343 /* Enable basic notifications */ 1342 - ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR; 1343 - command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; 1344 + ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR; 1345 + command = UCSI_SET_NOTIFICATION_ENABLE | ntfy; 1344 1346 ret = ucsi_send_command(ucsi, command, NULL, 0); 1345 1347 if (ret < 0) 1346 1348 goto err_reset; ··· 1357 1359 } 1358 1360 1359 1361 /* Allocate the connectors. Released in ucsi_unregister() */ 1360 - ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1, 1361 - sizeof(*ucsi->connector), GFP_KERNEL); 1362 - if (!ucsi->connector) { 1362 + connector = kcalloc(ucsi->cap.num_connectors + 1, sizeof(*connector), GFP_KERNEL); 1363 + if (!connector) { 1363 1364 ret = -ENOMEM; 1364 1365 goto err_reset; 1365 1366 } 1366 1367 1367 1368 /* Register all connectors */ 1368 1369 for (i = 0; i < ucsi->cap.num_connectors; i++) { 1369 - ret = ucsi_register_port(ucsi, i); 1370 + connector[i].num = i + 1; 1371 + ret = ucsi_register_port(ucsi, &connector[i]); 1370 1372 if (ret) 1371 1373 goto err_unregister; 1372 1374 } 1373 1375 1374 1376 /* Enable all notifications */ 1375 - ucsi->ntfy = UCSI_ENABLE_NTFY_ALL; 1376 - command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; 1377 + ntfy = UCSI_ENABLE_NTFY_ALL; 1378 + command = UCSI_SET_NOTIFICATION_ENABLE | ntfy; 1377 1379 ret = ucsi_send_command(ucsi, command, NULL, 0); 1378 1380 if (ret < 0) 1379 1381 goto err_unregister; 1380 1382 1383 + ucsi->connector = connector; 1384 + ucsi->ntfy = ntfy; 1381 1385 return 0; 1382 1386 1383 1387 err_unregister: 1384 - for (con = ucsi->connector; con->port; con++) { 1388 + for (con = connector; con->port; con++) { 1385 1389 ucsi_unregister_partner(con); 1386 1390 ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); 1387 1391 ucsi_unregister_port_psy(con); ··· 1399 1399 typec_unregister_port(con->port); 1400 1400 con->port = NULL; 1401 1401 } 1402 - 1403 - kfree(ucsi->connector); 1404 - ucsi->connector = NULL; 1405 - 1402 + kfree(connector); 1406 1403 err_reset: 1407 1404 memset(&ucsi->cap, 0, sizeof(ucsi->cap)); 1408 1405 ucsi_reset_ppm(ucsi);
+1 -1
drivers/usb/typec/ucsi/ucsi_acpi.c
··· 78 78 if (ret) 79 79 goto out_clear_bit; 80 80 81 - if (!wait_for_completion_timeout(&ua->complete, HZ)) 81 + if (!wait_for_completion_timeout(&ua->complete, 5 * HZ)) 82 82 ret = -ETIMEDOUT; 83 83 84 84 out_clear_bit: