Bug 210736 - Disconnecting USB cable in device/gadget mode breaks usbconfig(8)
Summary: Disconnecting USB cable in device/gadget mode breaks usbconfig(8)
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-07-01 07:33 UTC by Edward Tomasz Napierala
Modified: 2016-07-11 13:01 UTC (History)
1 user (show)

See Also:


Attachments
DWC OTG patch (1.16 KB, patch)
2016-07-03 11:16 UTC, Hans Petter Selasky
no flags Details | Diff
DWC OTG patch (1.71 KB, patch)
2016-07-03 11:48 UTC, Hans Petter Selasky
no flags Details | Diff
DWC OTG patch (2.16 KB, patch)
2016-07-04 10:17 UTC, Hans Petter Selasky
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 07:33:42 UTC
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
Comment 1 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 07:37:26 UTC
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
Comment 2 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 09:12:09 UTC
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
Comment 3 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 09:25:28 UTC
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
Comment 4 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 09:58:40 UTC
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.
Comment 5 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 10:02:27 UTC
Is the console locked when this happens?

--HPS
Comment 6 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 10:06:14 UTC
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.
Comment 7 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 10:06:35 UTC
Yes, both cases make the system non-responsive.
Comment 8 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 10:11:30 UTC
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.
Comment 9 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 10:25:54 UTC
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
Comment 10 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 10:26:50 UTC
Do you have a multimeter to check if the +5V goes away after unplugging the USB device?

--HPS
Comment 11 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 10:37:07 UTC
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.
Comment 12 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 10:39:36 UTC
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?
Comment 13 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 10:46:38 UTC
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.
Comment 14 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 10:59:23 UTC
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.
Comment 15 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 11:01:32 UTC
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
Comment 16 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 11:24:11 UTC
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).
Comment 17 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 12:01:29 UTC
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
Comment 18 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 12:21:59 UTC
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.
Comment 19 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 12:40:01 UTC
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
Comment 20 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 13:33:36 UTC
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.
Comment 21 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 13:41:56 UTC
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
Comment 22 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-01 13:43:56 UTC
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
Comment 23 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-01 13:50:29 UTC
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.
Comment 24 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-02 10:05:51 UTC
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.
Comment 25 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-02 11:50:00 UTC
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.
Comment 26 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-02 14:15:22 UTC
Could you print the GINTSTS value from the interrupt filter to dmesg, so I can see which IRQ's are active?
Comment 27 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-02 14:19:32 UTC
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
Comment 28 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-02 17:11:52 UTC
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
Comment 29 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-02 17:13:51 UTC
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
Comment 30 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-03 11:16:05 UTC
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
Comment 31 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-03 11:48:58 UTC
Created attachment 172056 [details]
DWC OTG patch

Some minor improvements.
Comment 32 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-03 20:01:00 UTC
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
Comment 33 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-03 20:34:31 UTC
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
Comment 34 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-03 20:35:42 UTC
And also change:
                                DWC_OTG_WRITE_4(sc, DOTG_DIEPINT(x),
                                    DIEPMSK_XFERCOMPLMSK);
Into:
                                DWC_OTG_WRITE_4(sc, DOTG_DIEPINT(x),
                                    temp);

--HPS
Comment 35 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-04 09:59:50 UTC
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
Comment 36 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-04 10:17:35 UTC
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
Comment 37 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-04 14:25:24 UTC
I've tested the patch, and everything works as expected.  Apart from the USB error messages, of course.
Comment 38 commit-hook freebsd_committer freebsd_triage 2016-07-04 17:13:10 UTC
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
Comment 39 Edward Tomasz Napierala freebsd_committer freebsd_triage 2016-07-04 18:50:00 UTC
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.
Comment 40 Hans Petter Selasky freebsd_committer freebsd_triage 2016-07-04 18:57:25 UTC
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
Comment 41 commit-hook freebsd_committer freebsd_triage 2016-07-11 13:01:48 UTC
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