blob: e1cd41fa1dcec15b2603acbedfde7d0f9fca90e6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#!/bin/bash
# Thanks, ericwoud
# https://ubuntuforums.org/showthread.php?t=2339439&page=2&p=13585921#post13585921
warn() { printf 'Error: %s\n' "$*" >&2; }
with_rescan_remove()
{
local devname="$1" dev f hw_path rescan remove
shift
case "$devname" in
*/*)
dev=/sys/class/$devname ;;
*)
for f in /sys/class/*/"$devname"; do
dev=$f
break
done
;;
esac
[ "$dev" -a -d "$dev" ] || { warn "device not found: $devname"; return 1; }
hw_path=$(dirname $(dirname $(realpath "$(dirname "$dev")/$(readlink "$dev")")))
rescan=$(dirname "$hw_path")/rescan
remove="$hw_path"/remove
if [ ! -e "$rescan" -a -e "$hw_path"/../pci_bus ]; then
local p=$(dirname "$hw_path")/
rescan=$p/pci_bus/${p#*/pci}/rescan
fi
[ -e "$rescan" ] || { warn "sysfs special file not found: $rescan"; return 1; }
[ -e "$remove" ] || { warn "sysfs special file not found: $remove"; return 1; }
"$@" "$rescan" "$remove"
}
restart()
{
local rescan="$1" remove="$2"
printf 1 > "$remove" || { warn "kernel remove failed"; return 2; }
printf 1 > "$rescan" || { warn "kernel rescan failed"; return 3; }
for ((i=0; i<100; ++i)); do
[ -e "$remove" ] && break
sleep 0.05
done
}
with_rescan_remove "$1" restart
|