-
Notifications
You must be signed in to change notification settings - Fork 34
Scatter/gather list failure with Basler camera under Debian Bullseye...? #12
Description
I'm trying to get the latest U3V working under Debian Bullseye, but this is yielding lots of scatter/gather list failures like this:
usb 7-1: calculate_sglist_entries: invalid buffer: if sg_constraint is true, a buffer can only have a scatterlist entry smaller than w_max_packet_size if it's the first or last in the list
usb 7-1: create_buffer: Creating sglist failed with error -131072
Enabling the debug output in calculate_urb_sizes prints out this:
[ 121.185909] usb 7-1: calculate_urb_sizes: host image buffer size = 4608000
[ 121.193996] usb 7-1: calculate_urb_sizes: device image buffer size = 4608000
[ 121.202303] usb 7-1: calculate_urb_sizes: chunk data buffer size = 64
[ 121.209867] usb 7-1: calculate_urb_sizes: payload size = 65536
[ 121.216746] usb 7-1: calculate_urb_sizes: payload count = 70
[ 121.223409] usb 7-1: calculate_urb_sizes: transfer1 = 20480
[ 121.229981] usb 7-1: calculate_urb_sizes: transfer2 = 64
[ 121.236223] usb 7-1: calculate_urb_sizes: transfer2_data = 64
[ 121.242999] usb 7-1: calculate_urb_sizes: max_pglist_count = 1
[ 121.249871] usb 7-1: calculate_urb_sizes: alignment_padding = 0
[ 121.256818] usb 7-1: calculate_urb_sizes: segment_padding = 0
[ 121.263565] usb 7-1: calculate_urb_sizes: segment_size = 4608000
[ 121.270641] usb 7-1: calculate_urb_sizes: sg_constraint = true
The problem seems to be that if the desired first USB transaction length of a set is not a multiple of the max packet size (i.e. before being clipped), then the code can cause a second consecutive non-multiple of the max packet size to be emitted, depending on the page alignment.
The specific case causing the problem for me has bytes_remaining = 65536, which is triggering an initial bytes_to_transfer value of 2944, which is then being rounded down to 2048 (because the max packet size is 1024). The second packet is then getting sized to 896 bytes (to go to the page boundary), which is triggering the error condition.
My patch attempting to fix this issue looks like this:
if (stream->config.sg_constraint) {
if (bytes_to_transfer > w_max_packet_size) {
// If this isn't the first packet or the last packet
if ( (sg_count != 0) && (bytes_to_transfer != pglist_bytes_remaining) ) {
// If the transfer size is not a multiple of the packet size
int remainder = bytes_to_transfer % w_max_packet_size;
if (remainder) {
// Round the transfer size down to be a multiple of the packet size
bytes_to_transfer -= remainder;
}
}
} else if (bytes_to_transfer < w_max_packet_size
This prevents the scatter/gather failures, but instead yields a different warning when the packet is received:
[ 2382.175004] usb 7-1: stream_urb_completion: entry 90, urb 72: length = 40, expected >=64
So I'm not sure if my fix is actually fixing the problem.
Is this whole thing a known issue? Or might it be being triggered by something else entirely, e.g. the memory alignment of the USB buffers?