Created
January 31, 2025 11:06
-
-
Save ThomasKaiser/2c2bd04539a64a906f5520432a651d1d to your computer and use it in GitHub Desktop.
set-samsung-speed.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# script to set link speed of Samsung NVMe SSDs to $1 | |
# | |
# almost completely based on https://www.alexforencich.com/wiki/en/pcie/set-speed | |
# (archived at https://archive.ph/dRb6z) | |
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin | |
setspeed() { | |
dev=$1 | |
speed=$2 | |
if [ ! -e "/sys/bus/pci/devices/$dev" ]; then | |
dev="0000:$dev" | |
fi | |
if [ ! -e "/sys/bus/pci/devices/$dev" ]; then | |
echo "Error: device $dev not found" | |
exit 1 | |
fi | |
pciec=$(setpci -s $dev CAP_EXP+02.W) | |
pt=$((("0x$pciec" & 0xF0) >> 4)) | |
port=$(basename $(dirname $(readlink "/sys/bus/pci/devices/$dev"))) | |
if (($pt == 0)) || (($pt == 1)) || (($pt == 5)); then | |
dev=$port | |
fi | |
lc=$(setpci -s $dev CAP_EXP+0c.L) | |
ls=$(setpci -s $dev CAP_EXP+12.W) | |
max_speed=$(("0x$lc" & 0xF)) | |
echo "Link capabilities:" $lc | |
echo "Max link speed:" $max_speed | |
echo "Link status:" $ls | |
echo "Current link speed:" $(("0x$ls" & 0xF)) | |
if [ -z "$speed" ]; then | |
speed=$max_speed | |
fi | |
if (($speed > $max_speed)); then | |
speed=$max_speed | |
fi | |
echo "Configuring $dev..." | |
lc2=$(setpci -s $dev CAP_EXP+30.L) | |
echo "Original link control 2:" $lc2 | |
echo "Original link target speed:" $(("0x$lc2" & 0xF)) | |
lc2n=$(printf "%08x" $((("0x$lc2" & 0xFFFFFFF0) | $speed))) | |
echo "New target link speed:" $speed | |
echo "New link control 2:" $lc2n | |
setpci -s $dev CAP_EXP+30.L=$lc2n | |
echo "Triggering link retraining..." | |
lc=$(setpci -s $dev CAP_EXP+10.L) | |
echo "Original link control:" $lc | |
lcn=$(printf "%08x" $(("0x$lc" | 0x20))) | |
echo "New link control:" $lcn | |
setpci -s $dev CAP_EXP+10.L=$lcn | |
sleep 0.1 | |
ls=$(setpci -s $dev CAP_EXP+12.W) | |
echo "Link status:" $ls | |
echo "Current link speed:" $(("0x$ls" & 0xF)) | |
} # setspeed | |
LinkSpeed="$1" | |
if [ -z "${LinkSpeed}" ]; then | |
echo "Error: no link speed specified. Needs to be 1 to 4. Exiting" | |
exit 1 | |
fi | |
lspci | awk -F" " '/Samsung/ {print $1}' | while read ; do | |
setspeed "${REPLY}" ${LinkSpeed} >/dev/null | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment