There is an approach made to implement gs_usb firmware/driver based on Zephyr RTOS. It was found that USB stack of Zephyr RTOS overwrites USB EP addresses, if they have different last 4 bytes in absence of other endpoints. For example in case of gs_usb candlelight firmware EP-IN is 0x81 and EP-OUT 0x02. If there are no additional USB endpoints, Zephyr RTOS will overwrite EP-OUT to 0x01. More information can be found in the discussion with Zephyr RTOS USB stack maintainer here: https://github.com/zephyrproject-rtos/zephyr/issues/67812 There are already two different gs_usb FW driver implementations based on Zephyr RTOS: 1. https://github.com/CANnectivity/cannectivity (by: https://github.com/henrikbrixandersen) 2. https://github.com/zephyrproject-rtos/zephyr/compare/main...KozhinovAlexander:zephyr:gs_usb (by: https://github.com/KozhinovAlexander) At the moment both Zephyr RTOS implementations use dummy USB endpoint, to overcome described USB stack behavior from Zephyr itself. Since Zephyr RTOS is intended to be used on microcontrollers with very constrained amount of resources (ROM, RAM) and additional endpoint requires memory, it is more convenient to update the gs_usb driver in the Linux kernel. To fix this problem, update the gs_usb driver from using hard coded endpoint numbers to evaluate the endpoint descriptors and use the endpoints provided there. Cc: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> Cc: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> Cc: David S. Miller <davem@xxxxxxxxxxxxx> Cc: Eric Dumazet <edumazet@xxxxxxxxxx> Cc: Jakub Kicinski <kuba@xxxxxxxxxx> Cc: Paolo Abeni <pabeni@xxxxxxxxxx> Cc: Maximilian Schneider <max@xxxxxxxxxxxxxxxxx> Signed-off-by: Alexander Kozhinov <ak.alexander.kozhinov@xxxxxxxxx> --- drivers/net/can/usb/gs_usb.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index bc86e9b329fd..f3eb447267f9 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -43,9 +43,6 @@ #define USB_XYLANTA_SAINT3_VENDOR_ID 0x16d0 #define USB_XYLANTA_SAINT3_PRODUCT_ID 0x0f30 -#define GS_USB_ENDPOINT_IN 1 -#define GS_USB_ENDPOINT_OUT 2 - /* Timestamp 32 bit timer runs at 1 MHz (1 µs tick). Worker accounts * for timer overflow (will be after ~71 minutes) */ @@ -336,6 +333,9 @@ struct gs_usb { unsigned int hf_size_rx; u8 active_channels; + + u8 ep_in; + u8 ep_out; }; /* 'allocate' a tx context. @@ -687,7 +687,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) resubmit_urb: usb_fill_bulk_urb(urb, parent->udev, - usb_rcvbulkpipe(parent->udev, GS_USB_ENDPOINT_IN), + usb_rcvbulkpipe(parent->udev, parent->ep_in), hf, dev->parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); @@ -819,7 +819,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, } usb_fill_bulk_urb(urb, dev->udev, - usb_sndbulkpipe(dev->udev, GS_USB_ENDPOINT_OUT), + usb_sndbulkpipe(dev->udev, dev->parent->ep_out), hf, dev->hf_size_tx, gs_usb_xmit_callback, txc); @@ -926,7 +926,7 @@ static int gs_can_open(struct net_device *netdev) usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, - GS_USB_ENDPOINT_IN), + dev->parent->ep_in), buf, dev->parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); @@ -1421,6 +1421,18 @@ static int gs_usb_probe(struct usb_interface *intf, struct gs_device_config dconf; unsigned int icount, i; int rc; + struct usb_host_interface *host_iface; + struct usb_endpoint_descriptor *ep_in, *ep_out; + + host_iface = intf->cur_altsetting; + + /* Find common bulk endpoints reverse */ + rc = usb_find_common_endpoints_reverse(host_iface, &ep_in, &ep_out, NULL, + NULL); + if (rc) { + dev_err(&intf->dev, "Required endpoints not found\n"); + return rc; + } /* send host config */ rc = usb_control_msg_send(udev, 0, @@ -1466,6 +1478,10 @@ static int gs_usb_probe(struct usb_interface *intf, usb_set_intfdata(intf, parent); parent->udev = udev; + /* store the detected endpoints */ + parent->ep_in = ep_in->bEndpointAddress; + parent->ep_out = ep_out->bEndpointAddress; + for (i = 0; i < icount; i++) { unsigned int hf_size_rx = 0; -- 2.43.0