I am trying to have my Jetson Orin Nano send frames as if it were a UVC Camera. It is going to get frames from a proprietary application and send them over the streaming interface. The application exposes settings that can be changed and I want to manipulate them as if they were UVC controls as laid out in the UVC specification. I am using a patched version of Linux’s UVC gadget driver (kernel version 5.10.104) that allows for me to set the camera and processing controls in configfs and set up extension units. The device is able to stream frames and handle successful control requests. However, the device seems to be having trouble with handling failed control requests. When a UVC control request cannot be completed, the specification states:
(UVC 1.5 Specification section 2.4.4 “Control Transfer and Request Processing”)
The device shall use protocol STALL (not function stall) during the Data or Status stages if the device is unable to complete the Control transfer (see section 8.5.3.4 of the USB Specification
Revision 2.0). Reasons for protocol STALL include unsupported operations, invalid target entity, invalid control selector, unexpected Data length, or invalid Data content. The device shall update the value of Request Error Code Control, and the host may use that control to determine the reason for the protocol STALL (see section 4.2.1.2 “Request Error Code Control”). The device must not NAK or STALL the SETUP transaction.
I see two different things occurring depending if I have an error in a UVC_SET_* request or a UVC_GET_* request. If I have an error during a get request, the host is notified that an error occurred but any subsequent control requests will hang. Sending a request to the VC_REQUEST_ERROR_CODE_CONTROL to check which error occurred also hangs. If I have an error during a set request, the host is not notified that the request couldn’t be completed. Sending a subsequent request to the VC_REQUEST_ERROR_CODE_CONTROL will contain the error code for the error that occurred.
I did some tests with UVC controls on a Raspberry PI Zero 2W device with a separate uvc-gadget application (uvc-gadget.git - UVC gadget userspace sample application) modified to return errors on control requests. The host was notified of an error, I was able to check the VC_REQUEST_ERROR_CODE_CONTROL for the error, and I was able to submit subsequent control requests.
Both the Pi and Orin Nano were using the Linux UVC gadget driver. However, the Orin Nano uses the tegra-xudc device controller and I believe the Pi uses the dwc2 device controller. Does the tegra-xudc device controller have any issues with the Linux UVC gadget driver in handling control requests?
The command “cat /etc/nv_tegra_release” prints out “# R35 (release), REVISION: 3.1, GCID: 32827747, BOARD: t186ref, EABI: aarch64, DATE: Sun Mar 19 15:19:21 UTC 2023”.
Attached is the UVC 1.5 specification for reference and the dmesg log file. I made sure to rebuild my kernel with “CONFIG_DYNAMIC_DEBUG=y” and I ran the command “echo ‘file tegra-xudc.c +p’ | sudo tee /sys/kernel/debug/dynamic_debug/control” so kernel messages in the tegra-xudc.c file would be printed in dmesg. I also ran “dmesg -n 8” to enable kernel messages.
I performed the following steps from a test program that uses libuvc to communicate with the gadget:
I start the gadget user space program (dmesg.log:1)
Opened device on host using libuvc library (dmesg.log:821)
I start sending controls (dmesg.log:1055)
Sent SET_CUR request to CT_ZOOM_ABSOLUTE_CONTROL to change wObjectiveFocalLength to 63
-uvc_get_ctrl has no error on host side
Sent GET_CUR request to VC_REQUEST_ERROR_CODE_CONTROL to retrieve bRequestErrorCode
-uvc_get_ctrl has no error on host side
-bRequestErrorCode = 0 (No error) on host side
Sent GET_CUR request to CT_ZOOM_ABSOLUTE_CONTROL to retrieve wObjectiveFocalLength
-uvc_get_ctrl has no error on host side
-wObjectiveFocalLength = 63 on host side
Sent GET_CUR request to VC_REQUEST_ERROR_CODE_CONTROL to retrieve bRequestErrorCode
-uvc_get_ctrl has no error on host side
-bRequestErrorCode = 0 (No error) on host side
Sent SET_CUR request to VC_VIDEO_POWER_MODE_CONTROL to change bDevicePowerMode to 0
-This control doesn’t exist so uvc_get_ctrl should have a pipe error for a protocol STALL occurring
-uvc_get_ctrl actually has no error on host side
Sent GET_CUR request to VC_REQUEST_ERROR_CODE_CONTROL to retrieve bRequestErrorCode
-uvc_get_ctrl has no error on host side
-bRequestErrorCode = 6 (Invalid control) on host side
Sent GET_MIN request to CT_AE_MODE_CONTROL to retrieve bAutoExposureMode
-This is an invalid request as CT_AE_MODE_CONTROL does not have a minimum value
-uvc_get_ctrl has a pipe error for a protocol STALL occurring
Sent GET_CUR request to VC_REQUEST_ERROR_CODE_CONTROL to retrieve bRequestErrorCode
-uvc_get_ctrl never returns
I stop the gadget user space program (dmesg.log:1135)
dmesg.log (112.3 KB)
UVC 1.5 Class specification.pdf (2.1 MB)