uvc: read fifo caps from debugfs
This commit is contained in:
parent
b6479acf11
commit
11c615d0b7
@ -131,12 +131,50 @@ uvc_fifo_min() {
|
||||
END { if (min != "") print min }'
|
||||
}
|
||||
|
||||
uvc_fifo_min_debugfs() {
|
||||
local path="$1"
|
||||
awk -F': ' '/^g_tx_fifo_size\\[/{print $2}' "$path" 2>/dev/null | awk '
|
||||
$1 > 0 { if (min == "" || $1 < min) min = $1 }
|
||||
END { if (min != "") print min }'
|
||||
}
|
||||
|
||||
uvc_fifo_np_debugfs() {
|
||||
local path="$1"
|
||||
awk -F': ' '/^g_np_tx_fifo_size/{print $2; exit}' "$path" 2>/dev/null
|
||||
}
|
||||
|
||||
compute_uvc_payload_cap() {
|
||||
UVC_PAYLOAD_CAP=""
|
||||
UVC_PAYLOAD_SRC=""
|
||||
UVC_PAYLOAD_PCT=""
|
||||
UVC_FIFO_PERIODIC="$(uvc_fifo_min /sys/module/dwc2/parameters/g_tx_fifo_size)"
|
||||
UVC_FIFO_NP="$(uvc_fifo_min /sys/module/dwc2/parameters/g_np_tx_fifo_size)"
|
||||
UVC_FIFO_SRC_PERIODIC=""
|
||||
UVC_FIFO_SRC_NP=""
|
||||
if [[ -n $UVC_FIFO_PERIODIC ]]; then
|
||||
UVC_FIFO_SRC_PERIODIC="dwc2.params"
|
||||
fi
|
||||
if [[ -n $UVC_FIFO_NP ]]; then
|
||||
UVC_FIFO_SRC_NP="dwc2.params"
|
||||
fi
|
||||
UVC_UDC="$(ls /sys/class/udc 2>/dev/null | head -n1 || true)"
|
||||
if [[ -n $UVC_UDC ]]; then
|
||||
local params="/sys/kernel/debug/usb/$UVC_UDC/params"
|
||||
if [[ -r $params ]]; then
|
||||
if [[ -z $UVC_FIFO_PERIODIC ]]; then
|
||||
UVC_FIFO_PERIODIC="$(uvc_fifo_min_debugfs "$params")"
|
||||
if [[ -n $UVC_FIFO_PERIODIC ]]; then
|
||||
UVC_FIFO_SRC_PERIODIC="debugfs.params"
|
||||
fi
|
||||
fi
|
||||
if [[ -z $UVC_FIFO_NP ]]; then
|
||||
UVC_FIFO_NP="$(uvc_fifo_np_debugfs "$params")"
|
||||
if [[ -n $UVC_FIFO_NP ]]; then
|
||||
UVC_FIFO_SRC_NP="debugfs.params"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n ${LESAVKA_UVC_MAXPAYLOAD_LIMIT:-} ]]; then
|
||||
UVC_PAYLOAD_CAP="${LESAVKA_UVC_MAXPAYLOAD_LIMIT}"
|
||||
@ -149,18 +187,18 @@ compute_uvc_payload_cap() {
|
||||
if [[ -n $UVC_BULK ]]; then
|
||||
if [[ -n $UVC_FIFO_NP ]]; then
|
||||
chosen="$UVC_FIFO_NP"
|
||||
UVC_PAYLOAD_SRC="dwc2.g_np_tx_fifo_size"
|
||||
UVC_PAYLOAD_SRC="${UVC_FIFO_SRC_NP:-dwc2.g_np_tx_fifo_size}"
|
||||
elif [[ -n $UVC_FIFO_PERIODIC ]]; then
|
||||
chosen="$UVC_FIFO_PERIODIC"
|
||||
UVC_PAYLOAD_SRC="dwc2.g_tx_fifo_size"
|
||||
UVC_PAYLOAD_SRC="${UVC_FIFO_SRC_PERIODIC:-dwc2.g_tx_fifo_size}"
|
||||
fi
|
||||
else
|
||||
if [[ -n $UVC_FIFO_PERIODIC ]]; then
|
||||
chosen="$UVC_FIFO_PERIODIC"
|
||||
UVC_PAYLOAD_SRC="dwc2.g_tx_fifo_size"
|
||||
UVC_PAYLOAD_SRC="${UVC_FIFO_SRC_PERIODIC:-dwc2.g_tx_fifo_size}"
|
||||
elif [[ -n $UVC_FIFO_NP ]]; then
|
||||
chosen="$UVC_FIFO_NP"
|
||||
UVC_PAYLOAD_SRC="dwc2.g_np_tx_fifo_size"
|
||||
UVC_PAYLOAD_SRC="${UVC_FIFO_SRC_NP:-dwc2.g_np_tx_fifo_size}"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -181,7 +219,7 @@ compute_uvc_payload_cap() {
|
||||
|
||||
compute_uvc_payload_cap
|
||||
if [[ -n $UVC_PAYLOAD_CAP && $UVC_PAYLOAD_CAP -gt 0 ]]; then
|
||||
log "UVC fifo periodic=${UVC_FIFO_PERIODIC:-?} np=${UVC_FIFO_NP:-?} cap=${UVC_PAYLOAD_CAP}B pct=${UVC_PAYLOAD_PCT:-?} src=${UVC_PAYLOAD_SRC:-?}"
|
||||
log "UVC fifo periodic=${UVC_FIFO_PERIODIC:-?} np=${UVC_FIFO_NP:-?} cap=${UVC_PAYLOAD_CAP}B pct=${UVC_PAYLOAD_PCT:-?} src=${UVC_PAYLOAD_SRC:-?} udc=${UVC_UDC:-?}"
|
||||
if ((UVC_MAXPACKET > UVC_PAYLOAD_CAP)); then
|
||||
log "clamping UVC maxpacket $UVC_MAXPACKET -> $UVC_PAYLOAD_CAP"
|
||||
UVC_MAXPACKET=$UVC_PAYLOAD_CAP
|
||||
|
||||
@ -807,21 +807,35 @@ fn compute_payload_cap(bulk: bool) -> Option<PayloadCap> {
|
||||
});
|
||||
}
|
||||
|
||||
let periodic_dw = read_fifo_min("/sys/module/dwc2/parameters/g_tx_fifo_size");
|
||||
let non_periodic_dw = read_fifo_min("/sys/module/dwc2/parameters/g_np_tx_fifo_size");
|
||||
let mut periodic = read_fifo_min("/sys/module/dwc2/parameters/g_tx_fifo_size")
|
||||
.map(|v| (v, "dwc2.params"));
|
||||
let mut non_periodic = read_fifo_min("/sys/module/dwc2/parameters/g_np_tx_fifo_size")
|
||||
.map(|v| (v, "dwc2.params"));
|
||||
if periodic.is_none() || non_periodic.is_none() {
|
||||
if let Some((p, np)) = read_debugfs_fifos() {
|
||||
if periodic.is_none() {
|
||||
periodic = p.map(|v| (v, "debugfs.params"));
|
||||
}
|
||||
if non_periodic.is_none() {
|
||||
non_periodic = np.map(|v| (v, "debugfs.params"));
|
||||
}
|
||||
}
|
||||
}
|
||||
let periodic_dw = periodic.map(|(v, _)| v);
|
||||
let non_periodic_dw = non_periodic.map(|(v, _)| v);
|
||||
|
||||
let (fifo_dw, source) = if bulk {
|
||||
if let Some(np) = non_periodic_dw {
|
||||
(np, "dwc2.g_np_tx_fifo_size")
|
||||
} else if let Some(p) = periodic_dw {
|
||||
(p, "dwc2.g_tx_fifo_size")
|
||||
if let Some((np, src)) = non_periodic {
|
||||
(np, src)
|
||||
} else if let Some((p, src)) = periodic {
|
||||
(p, src)
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
} else if let Some(p) = periodic_dw {
|
||||
(p, "dwc2.g_tx_fifo_size")
|
||||
} else if let Some(np) = non_periodic_dw {
|
||||
(np, "dwc2.g_np_tx_fifo_size")
|
||||
} else if let Some((p, src)) = periodic {
|
||||
(p, src)
|
||||
} else if let Some((np, src)) = non_periodic {
|
||||
(np, src)
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
@ -855,6 +869,36 @@ fn read_fifo_min(path: &str) -> Option<u32> {
|
||||
.min()
|
||||
}
|
||||
|
||||
fn read_debugfs_fifos() -> Option<(Option<u32>, Option<u32>)> {
|
||||
let udc = std::fs::read_dir("/sys/class/udc")
|
||||
.ok()?
|
||||
.filter_map(|e| e.ok())
|
||||
.filter_map(|e| e.file_name().into_string().ok())
|
||||
.next()?;
|
||||
let path = format!("/sys/kernel/debug/usb/{udc}/params");
|
||||
let text = std::fs::read_to_string(path).ok()?;
|
||||
let mut periodic: Option<u32> = None;
|
||||
let mut non_periodic: Option<u32> = None;
|
||||
for line in text.lines() {
|
||||
let mut parts = line.splitn(2, ':');
|
||||
let key = parts.next()?.trim();
|
||||
let val = parts.next()?.trim().parse::<u32>().ok()?;
|
||||
if key == "g_np_tx_fifo_size" {
|
||||
non_periodic = Some(val);
|
||||
} else if key.starts_with("g_tx_fifo_size[") && val > 0 {
|
||||
periodic = Some(match periodic {
|
||||
Some(prev) => prev.min(val),
|
||||
None => val,
|
||||
});
|
||||
}
|
||||
}
|
||||
if periodic.is_none() && non_periodic.is_none() {
|
||||
None
|
||||
} else {
|
||||
Some((periodic, non_periodic))
|
||||
}
|
||||
}
|
||||
|
||||
const IOC_NRBITS: u8 = 8;
|
||||
const IOC_TYPEBITS: u8 = 8;
|
||||
const IOC_SIZEBITS: u8 = 14;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user