Hardware is Raspberry Pi Zero, configured to work as USB device - usb_template.ko is loaded, hw.usb.template=8, there's getty listening on /dev/ttyU0 and there is a configured IP address on ue0. Problem: disconnecting the USB cable results in... well, nothing. Running "usbconfig" results in it hanging, ^T shows: load: 0.69 cmd: usbconfig 620 [USB config SX lock] 2.61r 0.00u 0.02s 0% 2004k
My theory: This happens because the getty doesn't see the read error from /dev/ttyU0 and close the device. Then the enumeration thread gets stuck. Can you check this? --HPS
Yup, it doesn't seem to happen if I comment out the "/dev/ttyU" ttys(5) entry and remove the IP address. But I don't think it should work that way - I'd expect the device to just go away, just like it happens on the host side. Also - there's something weird going on here. I've noticed two more bugs: 1. After unplugging RPi from the host and plugging in a flash key, the whole thing... hangs. I'm not sure how to debug it; the last messages I see on the serial port are: ugen0.2: <The FreeBSD Project> at usbus0 (disconnected) umodem0: at uhub0, port 1, addr 4 (disconnected) cdce0: at uhub0, port 1, addr 4 (disconnected) cdce0: Resuming 2. The same the other way around, replacing the USB mass storage device with the host connection, a similar hang occurs: ugen0.2: <The FreeBSD Project> at usbus0
1) The close thing is a bug in getty. It needs to be handled there. Else we will start leaking FD's. 2) Can you enable DWC OTG debugging = 16. It is probably some IRQ event not getting cleared when we switch the mode. --HPS
Ok. The first case looks like this: dwc_otg_roothub_exec: UR_GET_PORT_^@STATUS d^@wc_otg_xfer_do_fifo: dwc_otg_interrupt: GINTSTS=0x04000822 HAINT=0x00000000 HFNUM=0x000000f0 dwc_otg_interrupt: suspend interrupt dwc_otg_root_intr: dwc_otg_interrupt: GOTGCTL=0x000d0000 dwc_otg_vbus_interrupt: vbus = 1 dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_roothub_exec: UR_CLEAR_PORT_FEATURE on port 1 dwc_otg_roothub_exec: UR_GET_PORT_STATUS cdce0: Suspending dwc_otg_device_suspend: dwc_otg_roothub_exec: UR_SET_P^@ORT_FEATURE dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_roothub_e^@xec: UR_GET_PORT_STATUS dwc_otg_xfer_do_fifo: ^M^@ dwc_otg_interrupt: GINTSTS=0x05000021 HAINT=0x00000000 HFNUM=0xea603fff dwc_otg_interrupt: GINTSTS=0x05000021, HPRT=0x00021403 dwc_otg_root_intr: dwc_otg_root_intr: dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_roothub_exec: UR_CLEAR_PORT_FEATURE on port 1 ugen0.2: <The FreeBSD Project> at usbus0 (disconnected) dwc_otg_device_done: xfer=0xc2c1c0c0, endpoint=0xc2c1c878, error=5 dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: u^@modem0: at uhub0, port 1, addr 4 (disconnected) cdce0: at uhub0, port 1, addr 4 (disconnected) cdce0: Resuming dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_ot^@g_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_tim^@er: dwc_otg_timer: dwc_otg_timer: dwc^@_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_timer^@: dwc_otg_timer: dwc_ot^@g_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_roothub_exec: UR_CLEAR_PORT_FEATURE on port 1 dwc_otg_roothub^@_exec: UR_SET_PORT_FEATURE dwc_otg_roothub_exec: PORT RESET dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: ^@ dwc_otg_timer: dwc_otg_timer: dwc_otg_i^@nterrupt: GINTSTS=0x05000029 HAINT=0x00000000 HFNUM=0x101b0008 dwc_otg_interrupt: GINTSTS=0x05000029, HPRT=0x0000100d dwc_otg_root_intr: dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #112, needsof=1 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #168, needsof=0 dwc_otg_timer: dwc_otg_update_host^@_transfer_schedule_locked: SOF interrupt #488, needsof=1 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #544, needsof=0 dwc_otg_init_fifo: PTX/NPTX FIFO=4064 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #624, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #680, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #736, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #792, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #848, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #904, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #960, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1016, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1072, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1128, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1184, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1240, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1296, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1352, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1408, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1464, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1520, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1576, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1632, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1688, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1744, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1800, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1856, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1912, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1968, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #2024, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #32, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #88, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #144, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #200, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #256, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #312, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #368, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #424, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #480, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #536, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #592, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #648, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #704, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #760, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #816, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #872, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #928, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #984, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1040, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1096, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1152, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1208, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1264, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1320, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1376, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1432, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1488, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1544, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1600, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1656, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1712, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1768, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1824, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1880, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1936, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1992, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #0, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #56, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #112, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #168, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #224, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #280, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #336, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #392, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #448, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #504, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #560, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #616, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #672, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #728, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #784, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #840, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #896, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #952, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1008, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1064, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1120, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1176, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1232, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1288, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1344, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1400, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1456, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1512, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1568, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1624, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1680, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1736, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1792, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1848, needsof=0 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1904, needsof=0 ... and it goes on.
Is the console locked when this happens? --HPS
Second case: da0 at umass-sim0 bus 0 scbus0 target 0 lun 0 da0: <Kingston DataTraveler 3.0 PMAP> s/n 60A44C3FACCEBDC0496A4BA4dwc_otg_timer: detached (da0:umass-sim0:0:0:0): Periph destroyed dwc_otg_device_done: xfer=0xc2c1c0c0, endpoint=0xc2c1c878, error=5 dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_roothub_exec: UR_CLEAR_PORT_FEATURE on port 1 dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: [..] dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_timer: dwc_otg_timer: dwc_otg_timer: [..] dwc_otg_interrupt: GINTSTS=0x04001022 H^@AINT=0x00000000 HFNUM=0x00003fff dwc_otg_root_intr: dwc_otg_interrupt: GOTGCTL=0x000d0000 dwc_otg_vbus_interrupt: vbus = 1 dwc_otg_interrupt: GINTSTS=0x04002022 HAINT=0x00000000 HFNUM=0x1ad007f7 dwc_otg_interrupt: end of reset dwc_otg_init_fifo: FIFO1 = IN:2048 / OUT:3072 dwc_otg_init_fifo: FIFO2 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO3 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO4 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO5 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO6 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO7 = IN:64 / OUT:3072 dwc_otg_set_address: addr=0 dwc_otg_root_intr: dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_roothub_exec: UR_CLEAR_PORT_FEATURE on port 1 dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_ep_init: endpoint=0xc2cd1078, addr=0, endpt=0, mode=1 (1,0) dwc_otg_clear_stall: endpoint=0xc2cd1078 ugen0.2: <The FreeBSD Project> at usbus0 dwc_otg_roothub_exec: UR_GET_PORT_STATUS dwc_otg_setup_standard_chain: addr=0 endpt=0 sumlen=8 speed=3 dwc_otg_start_standard_chain: dwc_otg_xfer_do_fifo: dwc_otg_xfer_do_complete_locked: dwc_otg_interrupt_poll_locked: Reading 8 bytes from ep 0 dwc_ot^@g_interrupt_poll_locked: RX status = 0x00ec0080: ch=0 pid=0 bytes=8 sts=6 dwc_otg_xfer_do_fifo: dwc_otg_setup_rx: GRXSTSR=0x00ec0080 dwc_otg_set_address: addr=4 dwc_otg_common_rx_ack: RX status clear dwc_otg_interrupt_poll_locked: Reading 0 bytes from ep 0 dwc_otg_interrupt_poll_locked: RX status = 0x01080000: ch=0 pid=0 bytes=0 sts=4 dwc_otg_xfer_do_fifo: dwc_otg_common_rx_ack: RX status clear dwc_otg_xfer_do_fifo: dwc_otg_interrupt: GINTSTS=0x040c802a HAINT=0x00000000 HFNUM=0x1156013c dwc_otg_xfer_do_complete_locked: dwc_otg_standard_done: xfer=0xc2ccf8c0 endpoint=0xc2cd1078 transfer done dwc_otg_standard_done_sub: dwc_otg_device_done: xfer=0xc2ccf8c0, endpoint=0xc2cd1078, error=0 dwc_otg_interrupt: GINTSTS=0x040c1022 H^@AINT=0x00000000 HFNUM=0x00000460 dwc_otg_root_intr: dwc_otg_interrupt: GOTGCTL=0x000d0000 dwc_otg_vbus_interrupt: vbus = 1 dwc_otg_interrupt: GINTSTS=0x040c2022 HAINT=0x00000000 HFNUM=0x0ec8046f dwc_otg_interrupt: end of reset dwc_otg_init_fifo: FIFO1 = IN:2048 / OUT:3072 dwc_otg_init_fifo: FIFO2 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO3 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO4 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO5 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO6 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO7 = IN:64 / OUT:3072 dwc_otg_set_address: addr=0 dwc_otg_root_intr: dwc_otg_interrupt_poll_locked: Reading 8 b^@ytes from ep 0 dwc_otg_interrupt_poll_locked: RX status = 0x00cc0080: ch=0 pid=0 bytes=8 sts=6 dwc_otg_interrupt: GINTSTS=0x0^@40c1032 HAINT=0x00000000 HFNUM=0x000002b4 dwc_otg_root_intr: dwc_otg_interrupt: GOTGCTL=0x000d0000 dwc_otg_vbus_interrupt: vbus = 1 dwc_otg_interrupt: GINTSTS=0x040c2032 HAINT=0x00000000 HFNUM=0x06e602c3 dwc_otg_interrupt: end of reset dwc_otg_init_fifo: FIFO1 = IN:2048 / OUT:3072 dwc_otg_init_fifo: FIFO2 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO3 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO4 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO5 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO6 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO7 = IN:64 / OUT:3072 dwc_otg_set_address: addr=0 dwc_otg_root_intr: dwc_otg_interrupt: GINTSTS=0x040c1032 HAINT=0x00000000 HFNUM=0x00000^@718 dwc_otg_root_intr: dwc_otg_interrupt: GOTGCTL=0x000d0000 dwc_otg_vbus_interrupt: vbus = 1 dwc_otg_interrupt: GINTSTS=0x040c2032 HAINT=0x00000000 HFNUM=0x1a450727 dwc_otg_interrupt: end of reset dwc_otg_init_fifo: FIFO1 = IN:2048 / OUT:3072 dwc_otg_init_fifo: FIFO2 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO3 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO4 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO5 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO6 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO7 = IN:64 / OUT:3072 dwc_otg_set_address: addr=0 dwc_otg_root_intr: dwc_otg_^@interrupt: GINTSTS=0x040c1032 HAINT=0x00000000 HFNUM=0x0000056e dwc_otg_root_intr: dwc_otg_interrupt: GOTGCTL=0x000d0000 dwc_otg_vbus_interrupt: vbus = 1 dwc_otg_interrupt: GINTSTS=0x040c2032 HAINT=0x00000000 HFNUM=0x1cca057d dwc_otg_interrupt: end of reset dwc_otg_init_fifo: FIFO1 = IN:2048 / OUT:3072 dwc_otg_init_fifo: FIFO2 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO3 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO4 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO5 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO6 = IN:1024 / OUT:3072 dwc_otg_init_fifo: FIFO7 = IN:64 / OUT:3072 dwc_otg_set_address: addr=0 dwc_otg_root_intr: dwc_otg_interrup^@t: GINTSTS=0x040c0832 HAINT=0x00000000 HFNUM=0x000001d1 dwc_otg_interrupt: suspend interrupt dwc_otg_root_intr: dwc_otg_interrupt: GOTGCTL=0x000d0000 dwc_otg_vbus_interrupt: vbus = 1 ... and that's it, no more messages, no reaction to keyboard.
Yes, both cases make the system non-responsive.
Also, correction on the first problem: it's not just getty, having the ue0 configured also makes the usbconfig(8) hang. The "ifconfig ue0 down" fixes it.
Are you sure it is not a ground issue? That you have a +5V shortcut somewhere? In host mode we deliver +5V and in gadget mode we are supposed to receive +5V, this is controlled by the OTG pin of the USB connector. --HPS
Do you have a multimeter to check if the +5V goes away after unplugging the USB device? --HPS
Can you tell me some more about this? I mean, the ground issue? The RPi was powered from the laptop USB all that time, via the second connector on the RPi. I've replaced it with a power bank, so the whole setup still has a common ground, but there is no 5V from the laptop. It doesn't seem to change anything.
Hm, to clarify: you want me to unplug the flash drive and then see if 5V line goes down on the USB connector from which I've unplugged the drive, right?
Ground issue: That you don't get a surge when you connect the ground parts together. +5V issue: Yes, check that +5V goes away after flash disk unplug.
It doesn't. 5V is there even when there's nothing connected to the USB port. Actually, it looks like it's hardwired to the second USB socket.
So maybe this is not a valid use-case. Either you power via OTG (gadget mode) or you power separately. Could you try to search a bit, and see if Linux's has the same problem? --HPS
Hm, not sure if I understand the problem. I mean, in the original case, the power is the same all the time - it's 5V from the laptop, through the first USB connector; the second one is connected to the same rail, either through RPi (with the flash drive) or both USB cables (when in the device mode).
Does this use-case work with Linux installed? If you connect the board to a USB host through the OTG port, will it get power that way and boot normal? I think you need to remove the power supply in order to use the OTG functionality. Else you'll end up with a short cut of some kind, unless you get the +5V from the same supply. --HPS
You won't get the short, exactly because it's the same 5V rail. Also - both cases alone work just fine, it's just that a reboot is needed when "changing the roles", because the system just hangs. I can try with Linux, but I need to figure out how to configure it there first.
OK. Maybe you can add a printf(".") in "dwc_otg_filter_interrupt()" to see if the hang is due to an IRQ issue. Else I guess it is something electrical. --HPS
Hm, I think I don't have to - at least in the case #1, the system is unresponsive, but there's still some timer and printfs going on. As in, the "dwc_otg_update_host_transfer_schedule_locked" stuff is printed over and over, indefinitely.
It is normal that DWC OTG messages are printed over and over again. I need to know if the IRQ handler is spinning printing it over and over again. I.E. that it leaves no time for other IRQs. --HPS
You might also want to try to compile a kernel with WITNESS enabled and enable it for spinlocks via debug.witness.skipspin=0 In /boot/loader.conf Might simply be some kind of deadlock. --HPS
What I've meant is, if it's printing over and over, then it's not electrical. I'll add the printf in dwc_otg_filter_interrupt() and test it.
Hm, I've realized something else. The board has two USB sockets, one fully functional, and one power only. So, I basically did the same test as before, but with the other socket. Electrically they are the same, it's just one of them doesn't have the data lines. So, my theory went, if it was an electrical fault, then doing the plugging and unplugging dance with power-only socket would cause the same problems as before. It didn't - everything is fine, the system works, not noticing any kind of activity on power-only USB socket.
Further update: WITNESS doesn't complain, even with debug.witness.skipspin=0. Adding a DPRINTF() to dwc_otg_filter_interrupt() shows that it's being called over and over again. It runs without any other messages in the second case (flash replaced with host connection), and interleaved with "dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #528, needsof=0" in the first case (host connection replaced with a flash) - there are three to ten interrupts per such a line.
Could you print the GINTSTS value from the interrupt filter to dmesg, so I can see which IRQ's are active?
To be more specific. In dwc_otg_filter_interrupt() add: printf("0x%08x 0x%08x\n", status, sc->sc_irq_mask); After: status = DWC_OTG_READ_4(sc, DOTG_GINTSTS); And send me the resulting prints. --HPS
First case (host -> flash): dwc_otg_filter_interrupt: 0x04000021 0xc3043014 dwc_otg_filter_interrupt: 0x04000029 0xc3043014 dwc_otg_filter_interrupt: 0x04000021 0xc3043014 dwc_otg_filter_interrupt: 0x04000029 0xc3043014 dwc_otg_filter_interrupt: 0x04000021 0xc3043014 Second case (flash -> host): dwc_otg_filter_interrupt: 0x040c8022 0x43043814 dwc_otg_filter_interrupt: 0x040c002a 0x43043814 dwc_otg_filter_interrupt: 0x040c8022 0x43043814 dwc_otg_filter_interrupt: 0x040c002a 0x43043814 dwc_otg_filter_interrupt: 0x040c8022 0x43043814 dwc_otg_filter_interrupt: 0x040c002a 0x43043814
Correction: after a moment, second case looks like this: dwc_otg_filter_interrupt: 0x040c0032 0xc3043004 dwc_otg_filter_interrupt: 0x040c0032 0xc3043004 dwc_otg_filter_interrupt: 0x040c0032 0xc3043004 dwc_otg_filter_interrupt: 0x040c0032 0xc3043004 dwc_otg_filter_interrupt: 0x040c0032 0xc3043004
Created attachment 172054 [details] DWC OTG patch Hi, Can you try the attached patch on top of the existing debug prints. Does it make any difference? --HPS
Created attachment 172056 [details] DWC OTG patch Some minor improvements.
Negative; the patch doesn't make it work. It changes the printed values, though. Output, first case: dwc_otg_filter_interrupt: 0x04000029 0xc1043014 dwc_otg_filter_interrupt: 0x04000021 0xc1043014 dwc_otg_filter_interrupt: 0x04000029 0xc1043014 dwc_otg_te_host_transfer_schedule_locked: SOF interrupt #1448, needsof=0 dwc_otg_filter_interrupt: 0x04000029 0xc1043014 dwc_otg_update_host_transfer_schedule_locked: SOF interrupt #1536, needsof=0 dwc_otg_filter_interrupt: 0x04000029 0xc1043014 dwc_otg_filter_interrupt: 0x04000021 0xc1043014 Second case: dwc_otg_filter_interrupt: 0x040c0032 0xc1043004 dwc_otg_filter_interrupt: 0x040c0032 0xc1043004 dwc_otg_filter_interrupt: 0x040c0032 0xc1043004 dwc_otg_filter_interrupt: 0x040c0032 0xc1043004 dwc_otg_filter_interrupt: 0x040c0032 0xc1043004 dwc_otg_filter_interrupt: 0x040c0032 0xc1043004 dwc_otg_filter_interrupt: 0x040c0032 0xc1043004 dwc_otg_filter_interrupt: 0x040c0032 0xc1043004
Hi, In the following piece of code: /* clear all IN endpoint interrupts */ if (status & GINTSTS_IEPINT) { uint32_t temp; uint8_t x; for (x = 0; x != sc->sc_dev_in_ep_max; x++) { temp = DWC_OTG_READ_4(sc, DOTG_DIEPINT(x)); if (temp & DIEPMSK_XFERCOMPLMSK) { ^^^^ change this if, to if (1) DWC_OTG_WRITE_4(sc, DOTG_DIEPINT(x), DIEPMSK_XFERCOMPLMSK); } } } Can you also add: if (temp != 0) printf("%d=0x%x\n", x, temp); if it doesn't help. Thank you! --HPS
And also change: DWC_OTG_WRITE_4(sc, DOTG_DIEPINT(x), DIEPMSK_XFERCOMPLMSK); Into: DWC_OTG_WRITE_4(sc, DOTG_DIEPINT(x), temp); --HPS
It works! There are some USB errors on the console, but other than that it seems to work just fine: umass0: <Kingston DataTraveler 3.0, class 0/0, rev 2.10/1.00, addr 2> on usbus0 umass0: SCSI over Bulk-Only; quirks = 0x8100 umass0:0:0: Attached to scbus0 da0 at umass-sim0 bus 0 scbus0 target 0 lun 0 da0: <Kingston DataTraveler 3.0 PMAP> Removable Direct Access SPC-4 SCSI device da0: Serial Number 60A44C3FACCEBDC0496A4BA4 da0: 40.000MB/s transfers da0: 7500MB (15360000 512 byte sectors) da0: quirks=0x2<NO_6_BYTE> ugen0.2: <Kingston> at usbus0 (disconnected) umass0: at uhub0, port 1, addr 2 (disconnected) da0 at umass-sim0 bus 0 scbus0 target 0 lun 0 da0: <Kingston DataTraveler 3.0 PMAP> s/n 60A44C3FACCEBDC0496A4BA4 detached (da0:umass-sim0:0:0:0): Periph destroyed ugen0.2: <The FreeBSD Project> at usbus0 umodem0: <USB Modem Interface> on usbus0 umodem0: data interface 1, has CM over data, has break cdce0: <USB Ethernet Comm Interface> on usbus0 ue0: <USB Ethernet> on cdce0 ue0: Ethernet address: 2a:23:45:67:89:54 cdce0: Suspending ugen0.2: <The FreeBSD Project> at usbus0 (disconnected) umodem0: at uhub0, port 1, addr 5 (disconnected) cdce0: at uhub0, port 1, addr 5 (disconnected) cdce0: Resuming usb_alloc_device: set address 2 failed (USB_ERR_TIMEOUT, ignored) usbd_setup_device_desc: getting device descriptor at addr 2 failed, USB_ERR_IOERROR usbd_req_re_enumerate: addr=2, set address failed! (USB_ERR_IOERROR, ignored) usbd_setup_device_desc: getting device descriptor at addr 2 failed, USB_ERR_TIMEOUT ugen0.2: <Kingston> at usbus0 umass0: <Kingston DataTraveler 3.0, class 0/0, rev 2.10/1.00, addr 2> on usbus0 umass0: SCSI over Bulk-Only; quirks = 0x8100 umass0:0:0: Attached to scbus0 uhub_explore: illegal enable change, port 1 da0 at umass-sim0 bus 0 scbus0 target 0 lun 0 da0: <Kingston DataTraveler 3.0 PMAP> Removable Direct Access SPC-4 SCSI device da0: Serial Number 60A44C3FACCEBDC0496A4BA4 da0: 40.000MB/s transfers da0: 7500MB (15360000 512 byte sectors) da0: quirks=0x2<NO_6_BYTE> ugen0.2: <Kingston> at usbus0 (disconnected) umass0: at uhub0, port 1, addr 2 (disconnected) da0 at umass-sim0 bus 0 scbus0 target 0 lun 0 da0: <Kingston DataTraveler 3.0 PMAP> s/n 60A44C3FACCEBDC0496A4BA4 detached (da0:umass-sim0:0:0:0): Periph destroyed ugen0.2: <The FreeBSD Project> at usbus0 umodem0: <USB Modem Interface> on usbus0 umodem0: data interface 1, has CM over data, has break cdce0: <USB Ethernet Comm Interface> on usbus0 ue0: <USB Ethernet> on cdce0 ue0: Ethernet address: 2a:23:45:67:89:54
Created attachment 172095 [details] DWC OTG patch Hi, Can you clean all patches in your tree "svn up" and apply the attached patch again, which should now include all changes needed and verify nothing is broken. Thank you! --HPS
I've tested the patch, and everything works as expected. Apart from the USB error messages, of course.
A commit references this bug: Author: hselasky Date: Mon Jul 4 17:12:22 UTC 2016 New revision: 302336 URL: https://svnweb.freebsd.org/changeset/base/302336 Log: Fix interrupt loop when switching from USB device to USB host mode by clearing all endpoint interrupt bits. PR: 210736 Approved by: re (glebius) MFC after: 1 week Changes: head/sys/dev/usb/controller/dwc_otg.c
Hm, wait, there's still something more - although not what most of this PR was about :-) The problem is: ignoring the terminal thing; if there's an IP address configured on ue0 on device side, it won't go away after unplugging, with usbconfig(8) hanging on the config lock. The workaround - kind of - is to plug in a flash drive; this makes the interface to go away.
Hi, Can you enable hw.usb.uhub.debug=17 and see what is going on when you unplug in gadget mode? It is most likely something in userspace not giving up its reference. --HPS
A commit references this bug: Author: hselasky Date: Mon Jul 11 13:01:43 UTC 2016 New revision: 302563 URL: https://svnweb.freebsd.org/changeset/base/302563 Log: MFC r302336: Fix interrupt loop when switching from USB device to USB host mode by clearing all endpoint interrupt bits. PR: 210736 Changes: _U stable/10/ stable/10/sys/dev/usb/controller/dwc_otg.c