Skip to content

Scatter/gather list failure with Basler camera under Debian Bullseye...? #12

@nickpelling

Description

@nickpelling

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions