Skip to content
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

kernel crash: USB ECM: echo_server #7364

Closed
qianfan-Zhao opened this issue May 6, 2018 · 10 comments
Closed

kernel crash: USB ECM: echo_server #7364

qianfan-Zhao opened this issue May 6, 2018 · 10 comments
Assignees
Labels
area: USB Universal Serial Bus bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug

Comments

@qianfan-Zhao
Copy link
Collaborator

qianfan-Zhao commented May 6, 2018

I am testing usb ecm function by using echo_server example on stm32f4, but kernel crased and print this informations on console:

***** USAGE FAULT *****
  Executing thread ID (thread): 0x200034a4
  Faulting instruction address:  0x800497c
  Division by zero
Fatal fault in ISR! Spinning...

Disassembly zephyr.elf and I know where failed, so I make a breakpoint and see what happens:

(gdb) b 750 if ep->maxpacket == 0
Breakpoint 1 at 0x800496c: file /home/qianfan/zephyr/ext/hal/st/stm32cube/stm32f4xx/drivers/src/stm32f4xx_ll_usb.c, line 750.
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, USB_EPStartXfer (USBx=0x50000000, 
    ep=0x200008dc <usb_dc_stm32_state+532>, dma=0 '\000')
    at /home/qianfan/zephyr/ext/hal/st/stm32cube/stm32f4xx/drivers/src/stm32f4xx_ll_usb.c:750
750           pktcnt = (ep->xfer_len + ep->maxpacket -1U)/ ep->maxpacket; 
(gdb) bt 
#0  USB_EPStartXfer (USBx=0x50000000, ep=0x200008dc <usb_dc_stm32_state+532>, 
    dma=0 '\000')
    at /home/qianfan/zephyr/ext/hal/st/stm32cube/stm32f4xx/drivers/src/stm32f4xx_ll_usb.c:750
#1  0x08003c7e in HAL_PCD_EP_Receive (hpcd=0x200006c8 <usb_dc_stm32_state>, 
    ep_addr=1 '\001', pBuf=0x20000c5c <usb_dc_stm32_state+1428> "", len=64)
    at /home/qianfan/zephyr/ext/hal/st/stm32cube/stm32f4xx/drivers/src/stm32f4xx_hal_pcd.c:1040
#2  0x0800a50e in usb_dc_ep_start_read (ep=1 '\001', 
    data=0x20000c5c <usb_dc_stm32_state+1428> "", max_data_len=64)
    at /home/qianfan/zephyr/drivers/usb/device/usb_dc_stm32.c:275
#3  0x0800aaac in usb_dc_ep_read_continue (ep=1 '\001')
    at /home/qianfan/zephyr/drivers/usb/device/usb_dc_stm32.c:552
#4  0x08007374 in usb_transfer (ep=1 '\001', data=0x20002e60 <rx_buf> "", dlen=1500, 
    flags=1, cb=0x8027b7d <ecm_read_cb>, cb_data=0x0)
    at /home/qianfan/zephyr/subsys/usb/usb_device.c:1230
#5  0x08027c80 in ecm_read_cb (ep=1 '\001', size=0, priv=0x0)
    at /home/qianfan/zephyr/subsys/usb/class/netusb/function_ecm.c:165
#6  0x08027cbe in ecm_connect (connected=true)
    at /home/qianfan/zephyr/subsys/usb/class/netusb/function_ecm.c:172
#7  0x080276b6 in netusb_connect_media ()
    at /home/qianfan/zephyr/subsys/usb/class/netusb/netusb.c:77
#8  0x08027700 in netusb_configure ()
    at /home/qianfan/zephyr/subsys/usb/class/netusb/netusb.c:95
---Type <return> to continue, or q <return> to quit---
#9  0x080277a4 in netusb_status_cb (status=USB_DC_CONFIGURED, 
    param=0x20008ad3 <_interrupt_stack+1795> "\001")
    at /home/qianfan/zephyr/subsys/usb/class/netusb/netusb.c:139
#10 0x0800693e in usb_set_configuration (config_index=1 '\001', alt_setting=0 '\000')
    at /home/qianfan/zephyr/subsys/usb/usb_device.c:500
#11 0x08006ab2 in usb_handle_std_device_req (setup=0x2000041c <usb_dev>, 
    len=0x2000042c <usb_dev+16>, data_buf=0x20000424 <usb_dev+8>)
    at /home/qianfan/zephyr/subsys/usb/usb_device.c:610
#12 0x08006cec in usb_handle_standard_request (setup=0x2000041c <usb_dev>, 
    len=0x2000042c <usb_dev+16>, data_buf=0x20000424 <usb_dev+8>)
    at /home/qianfan/zephyr/subsys/usb/usb_device.c:777
#13 0x08006560 in usb_handle_request (setup=0x2000041c <usb_dev>, 
    len=0x2000042c <usb_dev+16>, data=0x20000424 <usb_dev+8>)
    at /home/qianfan/zephyr/subsys/usb/usb_device.c:209
#14 0x0800665c in usb_handle_control_transfer (ep=0 '\000', 
    ep_status=USB_DC_EP_SETUP) at /home/qianfan/zephyr/subsys/usb/usb_device.c:275
#15 0x0800ac54 in HAL_PCD_SetupStageCallback (hpcd=0x200006c8 <usb_dc_stm32_state>)
    at /home/qianfan/zephyr/drivers/usb/device/usb_dc_stm32.c:642
#16 0x0800333c in HAL_PCD_IRQHandler (hpcd=0x200006c8 <usb_dc_stm32_state>)
    at /home/qianfan/zephyr/ext/hal/st/stm32cube/stm32f4xx/drivers/src/stm32f4xx_hal_pcd.c:384
#17 0x0800a252 in usb_dc_stm32_isr (arg=0x0)
    at /home/qianfan/zephyr/drivers/usb/device/usb_dc_stm32.c:134
#18 0x0800243e in _isr_wrapper ()
---Type <return> to continue, or q <return> to quit---
    at /home/qianfan/zephyr/arch/arm/core/isr_wrapper.S:124
#19 <signal handler called>
#20 0xaaaaaaaa in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) 
(gdb) 

seems the variable ep->maxpacket is zero. search ep->maxpacket and found it was only assignmented at HAL_PCD_EP_Open.

HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
{
  HAL_StatusTypeDef  ret = HAL_OK;
  PCD_EPTypeDef *ep;
  
  if ((ep_addr & 0x80U) == 0x80U)
  {
    ep = &hpcd->IN_ep[ep_addr & 0x7FU];
  }
  else
  {
    ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
  }
  ep->num   = ep_addr & 0x7FU;
  
  ep->is_in = (0x80U & ep_addr) != 0U;
  ep->maxpacket = ep_mps;

and HAL_PCD_EP_Open was called in usb_dc_ep_enable when usb_set_configuration. got the params of usb_set_configuration from bt, config_index=1, alt_setting=0.

usb_set_configuration enable which endpoint according to usb common descriptor, so i need take a look common_desc: (I had translated it to a easier read format by hand)

(gdb) p sizeof(common_desc)
$5 = 170
(gdb) x/170xb &common_desc

12 01 10 01 00 00 00 40 e3 2f 00 01 11 00 01 02 03 01 
09 02 50 00 02 01 00 c0 32 
09 04 00 00 01 02 06 00 00 
05 24 00 10 01 
05 24 06 00 01 
0d 24 0f 04 00 00 00 00 ea 05 00 00 00 
07 05 83 03 10 00 09  #EP_INT_03
09 04 01 00 00 0a 00 00 00  # Interface descriptor 1/0 
09 04 01 01 02 0a 06 00 00  # Interface descriptor 1/1
07 05 82 02 40 00 00  #EP_BULK_IN_82
07 05 01 02 40 00 00  #EP_BULK_OUT_01
04 03 09 04 
0e 03 5a 00 45 00 50 00 48 00 59 00 52 00 
10 03 55 00 53 00 42 00 2d 00 44 00 45 00 56 00 
0a 03 30 00 2e 00 30 00 31 00 
1a 03 30 00 30 00 30 00 30 00 35 00 45 00 30 00 30 00 35 00 33 00 30 00 31 00 
00 00

this line '09 04 01 01 02 0a 06 00 00 # Interface descriptor 1/1' changed alt_setting to 0x01, caused we haven't open EP_BULK_IN_82 and EP_BULK_OUT_01, let ep->maxpacket is zero, make kernel crased.

	if ((cur_config == config_index) &&
	    (cur_alt_setting == alt_setting)) {
		struct usb_dc_ep_cfg_data ep_cfg;
		/* endpoint found for desired config
		 * and alternate setting
		 */
		ep_cfg.ep_type =
		    p[ENDP_DESC_bmAttributes];
		ep_cfg.ep_mps =
		    (p[ENDP_DESC_wMaxPacketSize]) |
		    (p[ENDP_DESC_wMaxPacketSize + 1]
			    << 8);
		ep_cfg.ep_addr =
		    p[ENDP_DESC_bEndpointAddress];
		printk("-----EP %x\n", ep_cfg.ep_addr);
		usb_dc_ep_configure(&ep_cfg);
		usb_dc_ep_enable(ep_cfg.ep_addr);
	}
	break;

Yes I know what happens but don't know how to fix it. I will check usb ecm spec and see if this interface descriptor is really need:

09 04 01 00 00 0a 00 00 00 /* Interface descriptor 1/0 */
@qianfan-Zhao
Copy link
Collaborator Author

@jfischer-phytec-iot please have a look

@jfischer-no jfischer-no added bug The issue is a bug, or the PR is fixing a bug area: USB Universal Serial Bus labels May 6, 2018
@jfischer-no
Copy link
Collaborator

jfischer-no commented May 7, 2018

@zhaozhongchen It is valid to select the alternative interface configuration. Kindly, the stack should try to disable the endpoints before reconfiguring them, but it seems not be the problem here. Can you please try it with #5163? @ydamigos @loicpoulain FYI

@qianfan-Zhao
Copy link
Collaborator Author

qianfan-Zhao commented May 9, 2018

@jfischer-phytec-iot I had tried #5163 and it's doesn't work.

please notice that interface 1 has two altersetting, and the usb host only configued the first altersetting. EP82 and EP01 is belong to the second altersetting but nerver configued.

@loicpoulain
Copy link
Collaborator

@jfischer-phytec-iot, I will have a look by the end of the week.

@MaureenHelm MaureenHelm added the priority: medium Medium impact/importance bug label May 10, 2018
@loicpoulain
Copy link
Collaborator

So, I'm pretty sure issue happens because of this patch: #7206 (comment)

The connect_media callback is called on USB configuration status, however at this moment endpoints are not yet enabled (neither the interface), so trying to read/write endpoint is failing... Reverting this patch on your side should solve the issue.

We need to find a clean solution, A first change should consist in returning an error when trying to use a non enabled endpoint. Then we need to understand how to fix @finikorg patch without breaking rndis.

@nashif
Copy link
Member

nashif commented May 11, 2018

@finikorg can you please take a look?

@finikorg
Copy link
Collaborator

@jfischer-phytec-iot @loicpoulain I am thinking to define status_cb() in each function, so we would overcome the problem of common super-smart callback, opinions?

finikorg added a commit to finikorg/zephyr that referenced this issue May 15, 2018
Implement status callback.

Fixes: zephyrproject-rtos#7364

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
@finikorg
Copy link
Collaborator

@zhaozhongchen could you check my RFC PR mentioned above?

@qianfan-Zhao
Copy link
Collaborator Author

@finikorg sure, I will check it tomorrow

@qianfan-Zhao
Copy link
Collaborator Author

@finikorg #7551 works on my stm32f4 platform

nashif pushed a commit that referenced this issue May 26, 2018
Implement status callback.

Fixes: #7364

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: USB Universal Serial Bus bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Projects
None yet
Development

No branches or pull requests

6 participants