-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
usb/dwc2: Set correct state on gadget disconnect #3151
base: rpi-4.19.y
Are you sure you want to change the base?
Conversation
When operating as a USB device, when the device is disconnected the suspend interrupt is called rather than the disconnect interrupt, this results in the state remaining as "configured". This change changes the state to "not attached" instead when the suspend interrupt is called.
Please provide some more information about the issue:
|
Pi Zero W, powered via a pi power supply. Only tried the most recent kernel available through raspbian. This issue has been mentioned on the Pi forums a few times in the past without any resolution, also searching the web throws up results. |
Let me rephrase my second question, which interface powers the Raspberry Pi Zero W: dwc2 is under active development in the mainline kernel. So your patch should be submitted to linux-usb for a proper solution. But you're patch must be tested with a recent mainline kernel like Linux 5.2 before. |
PWR IN. I’m unsure whether this issue affects anything other than raspberry pi’s (external hardware around the OTG section, my colleague made a slight “improvement” on the OTG section on one of our boards which had unintended consequences with host/device detection so I know its always a possibility), it would seem somewhat of an oversight if it affected everything and I’d expect more results when searching for the issue, there are some generic search hits for it from a couple of years back but patches were submitted. I’ll see if I can try with a mainline kernel, I. don't suppose you have any links on setting up a system using such a beast? I suppose i could also try pulling the latest source for the dwc2 module and see if it compiles with my kernel. I only posted this “fix” as i posted a solution to this problem on the forums and one of the staff suggested i create a pull request so people can look at it. Regardless of my solution, its a problem on the Pi Zero W (and potentially other Pi’s) which means that you cant track the disconnected and enumerated state. I’ll admit it was a quick hack fix, but it works for me in my situation, at the very least hopefully it can cause some discussion about the problem. |
Please try to use this gist in order to compile the mainline kernel. You can use |
ok, will take a look and have a go. For what its worth, I’ve just looked at the history for the dwc2 module and can’t see any commits that look like they would have any effect on this, but I guess you never know until you try, ot holding my breath. |
@lategoodbye Hi, I've followed the instructions with the latest mainline, kernel modules installed, device tree overlay copied and selected. Kernel starts to boot and then stops at "Waiting for root device" Switch back to original kernel, system boots fine. Any ideas? |
I also tried getting the .confid out of the booted rapbian system and used that as the config for the kernel when building, still have same issue. |
This won't work, you will need to replace kernel and DTB. You will need to use make bcm2835_defconfig as config. Overlays doesn't work yet in mainline. Maybe you can provide your dmesg and config.txt. |
ok, will try again. No boot log, I've just ordered a USB to TTL adaptor so I can hook up a terminal to capture everything. I'll repull the repo and build from fresh and try again. Thanks for your support, much appreciated! |
Btw are you using the stable tree e.g. git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git ? |
No, I was using the version that was in the gist, I'm just pulling the stable now. |
The torvalds tree is also okay, you will need to choose a final release like v5.2.0 |
Ok, so I have kernel booted, but a lot of stuff appears not to work, I don't seem to be able to load the dwc2 module and there's a whole load of errors about missing firmware.
|
Congratulation, you successful compiled a mainline kernel. dwc2 is working fine (no module, it's compiled in). Don't care about Wifi firmware, it's not relevant for the issue. Are you able to reproduce the issue or are the sysfs entries missing? |
ok, f_hid is disabled in this kernel, time to build another kernel image. Everything else looks good, UDC is appearing. |
@lategoodbye Same issue, disconnect the cable and the Pi Zero W still thinks it's in a configured state.
It's definitely broken. |
"Great". Please apply your patch to your mainline repo and retest. After that you need to report this issue (including reference to this issue and your inlined patch) via email to the following addresses: Thanks |
Ok, let me do a little more testing and reading and if I need to amend I will, then I'll submit a patch. What happens if this issue only occurs on the Pi? I guess the people looking at the patch will try without it first to see they can reproduce it on their hardware? |
It's a bug and you were able to reproduce with a mainline kernel reliable. Don't be afraid this might be specific to the Pi (which i don't believe). It's job of the maintainers to decide, how to fix this. So don't waste too much time with preparing the "perfect" patch. This can be done afterwards. |
Ok, thanks for all your time, help and advice, it's been much appreciated, I've never really delved into the kernel on linux (I did on the now dead ucLinux where I wrote some drivers for stuff). This particular bug is particularly annoying in that I found it straight away while conducting tests for using a Pi Zero W as a USB gadget (It's actually a bridge to make a Bluetooth Keyboard into a USB HID keyboard so I an use it with ESXi) and while I stormed through all the initial tests, enumeration, getting the actual "bridge" working I then hit a roadblock when it came to detecting whether the USB device was connected, bluetooth I get udev events, but USB requires monitoring that state file and that's when the trouble started. |
Quick question, I hooked up a serial console and while it works with the raspbian kernel I get no output when booting my 5.3 kernel, is this a limitation of the mainline kernel? I looked about the config and everything that should be enabled (AFAIK) is enabled. |
Ahh, it moves the serial port. Changed by console parameter to console=ttyS1,115200 and now I get console output. (Although not the complete log, it starts some time after boot) |
The downstream kernel has some patches to simplify the UART naming. Please use ttyAMA0 or ttyS1. But it should provide the complete log. |
its weird, it definitely misses off the start, when the terminal appears i’m getting junk being rx’d, i will try a different USB to serial just in case. on an aside, ive just been looking around everywhere as ive been involved in another conversation about a usb library, it was suggested to use extcon to monitor gadget connection and disconnection events but the DWC2 driver has no references to the extcon API. I’ve also ben studying the devicetree for the RPI device, and given that theres no schematics I’m assuming the phy is part of the DWC2 IP. so is there any way of reading the VBUS state (level)? i eventually ended up reading a post in the kernel dev about the DWC2 driver by yourself! |
It's possibly an issue with the baud rate. Yes, i also assume the PHY is part of the DWC2 IP. Unfortunately we don't have a PHY driver yet, the devicetree fake this via non-op driver. Maybe this is the root cause of this issue. The BCM2835 datasheet provides a register description for MDIO access incl. VBUS interrupt. I already started a template for a PHY driver: In case you need a datasheet for the DWC2 IP, try to google for Silicon Labs EZR32WG. It seems to use the same core. |
Awesome, I really appreciate your knowledge and help here. i’ll take a look at that document and have a read up on the VBUS interrupt to see if theres anything useful there, I’m trying to figure out a sane way of managing kernel rebuilds and transfer to the SD without network (in the case where i break the kernel) or taking apart my Pi Zero and removing the SD. |
@lategoodbye i’ve had a quick skim of that datasheet and i concur its the same core. Having a read about as well, they (synopsis) also do phy ip, so we really have to guess at what the phy is. The vbus sensing on that gecko part is done through a usb register, however, its located not in the same area of memory which means its not part of the core ip, its some other ip. so without knowing how to read vbus, gadget mode is never going to work “as it should”. my hack is a fix for my particularl circumstance, but its not the correct fix. the correct fix requires the raspberry pi foundation to release some information on how to read the vbus information. |
Is the MDIO register definition (p. 203 ff) in the BCM2835 datasheet not sufficient? |
I followed the instructions on the “how to format a patch” on the kernel page, it said to take the base from the one listed in the maintainers file. It’s more than possible I’ve messed up or done it wrong, I tried to take my time and looked at how other patches had been submitted. This is a bit of learning experience and probably a trial by fire! |
Thanks for take care of this Issue from me, too. |
@fizzyade @sn00pster I have encountered this problem on my Pi-KVM devices. Sorry to ask, was there any progress with the kernel devs? As far as I understood, there was only one answer to this patch. So is this problem specific to the Raspberry Pi or what? 2all: if so, maybe it's worth accepting this patch here? |
I agree, if this problem is present only on Rpi (because it do not use a PHI) this patch should be accepted here. |
@mdevaev Could you please tell which kernel version is affected? I don't see the reason why this shouldn't be fixed upstream. |
@lategoodbye affected:
But in fact all kernels I used were affected by this problem at least in recent year. Also it might be related: #3870 |
(Edited) ^^^ I have a large user base that uses OTG with different machines, and this is evident on absolutely all devices in our cases. So it's not just my local problem :( |
And there's also #3862. Clearly libcomposite issues are like buses - you wait years for one and then two or three arrive together. |
They might not be related, but Occam's razor would suggest that they might. Either way, I'll be looking at libcomposite. |
This patch has been merged offline into rpi-5.4.y. |
Thanks! |
For all boards: - raspberrypi/linux#3870 - raspberrypi/linux#3151 For zero: - raspberrypi/linux#3602
Okay, after #3885 I tried this (I repeat my comment to make it easier to understand the meaning):
So, I've tested it: diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 6272b4ae4740f..11c8893fbc1ab 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -539,13 +539,10 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
}
skip_power_saving:
/*
- * Change to L2 (suspend) state before releasing
- * spinlock
+ * Raspberry Pi seems to call the suspend interrupt on gadget disconnect,
+ * so instead of setting state to suspend set to not attach
*/
- hsotg->lx_state = DWC2_L2;
-
- /* Call gadget suspend callback */
- call_gadget(hsotg, suspend);
+ dwc2_hsotg_disconnect(hsotg);
}
} else {
if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) { No success. The device does not connect back:
Does anyone have any ideas how this should be implemented in the right way? |
I guess the reason is that |
@mdevaev Did you read this comment? |
@lategoodbye for some reason, I completely forgot about it. I didn't associate one problem with another. Well, that explains a lot. It seems that this requires the help of the community, but since I'm not a kernel/hw developer, it's unlikely that I personally could be of any use. Although, I could assign a bounty for solving this problem if it helps :) |
To be honest, I lost the will after a couple of weeks on the kernel mailing list, I pointed out the problem and that I had patched it which worked in my situation, and that it to me it looked like a problem that existed on everything that uses that driver. I was patient, but ultimately nobody seemed interested in solving the problem, so a year later it still exists. My patch (my previous account was @sn00pster) was a workaround, I don't profess that it is the correct fix, but it worked in my limited testing for the use I intended. It's a shame that the kernel list didn't seem bothered, but I'm also unsurprised. |
Just for the reference, i think this was the thread about the patch. I thought we come to the point that the issue should be fixed by implementing the missing PHY driver. Btw i can't see any prove that other dwc2 "users" are affected. |
@fizzyade I understand your frustration. I once reported an API bug to the core mailing list that no one fixed. Postponed to API 2.0, lol. Not even documented. Anyway, right now I'm interested in solving this problem, but I can't help with code. Maybe a beer will do? A couple of dozen liters of beer. @lategoodbye Oh, I assure you, the problem is really exists. The fact that it was not noticed earlier is due to the fact that this functionality was almost never used the way I use it. For about the same reason, #3870 remained in the kernel for years: very few people used dwc2 for the boot keyboard emulator and could not notice that OOPS happened due to frequent reinitializations of the host. Now my KVM software (which uses dwc2 very actively in a variety of configurations) has raised all these problems. It is used by thousands of people and they all bring me messages about USB problems. Detection of the keyboard connection state is usually performed by indirect signs, such as EAGAIN during writing and other. Now when I tried to use the port state and gave it to my users, we found that state was lying :) |
I don't want to make any pressure or stress to you guys but is there a chance to get a fix for this state-stuck-issue sometime? |
I tried to, I joined the kernel mailing list but was pretty much ignored when I bought up the issue and also my workaround, which worked for me in my situation but ymmv.
Nobody seemed interested in the problem and I was unable to find out if this was somethin specific to the pi or a more general issue with the dwc2 driver.
…On 28 Feb 2021, 15:06 +0000, Preston-Coding ***@***.***>, wrote:
I don't want to make any pressure or stress to you guys but is there a chance to get a fix for this state-stuck-issue sometime?
Its really annoying to have the intended way to determine the usb connection state and struggle at it because the driver not change it. :(
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Should I initiate a signature list? :P Or can I help somehow else? Thanks for take care of that issue! |
I'm also interested in the solution, but all I can do right now is offer a small reward for it. |
I'm also having issues with that ad i'm using an atsama5d27 from microchip, that would really help, i don't see how i can do without a fix for this. |
In short, it can't be fixed since it's a hardware problem. I found out it while studying how the USB core on Rockchip works, it uses the same DWC2 as in Raspberry Pi. The USB state machine in DWC2 distinguishes the disconnection of the device from using the lack or availability of the power on the +5V-USB-IN line. Apparently, in Raspberry Pi, voltage is always applied to this line, so the USB core thinks that when disconnected, suspend occurs. When I talk about +5V, I don't mean the power supply of the entire Raspberry, I'm talking specifically about a special pin that should be on the BCM chip, which serves to determine whether there is power on USB. |
When operating as a USB device, when the device is disconnected the suspend interrupt is called rather than the disconnect interrupt, this results in the state remaining as "configured". This change changes the state to "not attached" instead when the suspend interrupt is called.
I don't know whether this patch interferes with anything else or whether it's the correct way of "fixing" this issue, there is chatter on the web about similar behaviour a long time ago but patches were submitted, so I don't know whether this is something which is just affecting the hardware implementation on the Pi.
Without the correct state being reflected, it's not possible to detect when a gadget is connected and disconnected from a device as without this patch after enumeration even pulling the the cable the Pi device remains in "configured" state. With this patch it reverts back to "not attached".