mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 01:00:29 +08:00
switch: added ignore_hpd quirk for bad csi boards
This commit is contained in:
parent
02740aef37
commit
6a08fab818
@ -506,8 +506,9 @@ def _get_config_scheme() -> dict:
|
||||
},
|
||||
|
||||
"switch": {
|
||||
"device": Option("/dev/kvmd-switch", type=valid_abs_path, unpack_as="device_path"),
|
||||
"default_edid": Option("/etc/kvmd/switch-edid.hex", type=valid_abs_path, unpack_as="default_edid_path"),
|
||||
"device": Option("/dev/kvmd-switch", type=valid_abs_path, unpack_as="device_path"),
|
||||
"default_edid": Option("/etc/kvmd/switch-edid.hex", type=valid_abs_path, unpack_as="default_edid_path"),
|
||||
"ignore_hpd_on_top": Option(False, type=valid_bool),
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@ -84,11 +84,12 @@ class Switch: # pylint: disable=too-many-public-methods
|
||||
device_path: str,
|
||||
default_edid_path: str,
|
||||
pst_unix_path: str,
|
||||
ignore_hpd_on_top: bool,
|
||||
) -> None:
|
||||
|
||||
self.__default_edid_path = default_edid_path
|
||||
|
||||
self.__chain = Chain(device_path)
|
||||
self.__chain = Chain(device_path, ignore_hpd_on_top)
|
||||
self.__cache = StateCache()
|
||||
self.__storage = Storage(pst_unix_path)
|
||||
|
||||
|
||||
@ -177,8 +177,14 @@ class UnitAtxLedsEvent(BaseEvent):
|
||||
|
||||
# =====
|
||||
class Chain: # pylint: disable=too-many-instance-attributes
|
||||
def __init__(self, device_path: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
device_path: str,
|
||||
ignore_hpd_on_top: bool,
|
||||
) -> None:
|
||||
|
||||
self.__device = Device(device_path)
|
||||
self.__ignore_hpd_on_top = ignore_hpd_on_top
|
||||
|
||||
self.__actual = False
|
||||
|
||||
@ -293,6 +299,7 @@ class Chain: # pylint: disable=too-many-instance-attributes
|
||||
if self.__select():
|
||||
for resp in self.__device.read_all():
|
||||
self.__update_units(resp)
|
||||
self.__adjust_quirks()
|
||||
self.__adjust_start_port()
|
||||
self.__finish_changing_request(resp)
|
||||
self.__consume_commands()
|
||||
@ -364,6 +371,15 @@ class Chain: # pylint: disable=too-many-instance-attributes
|
||||
self.__units[resp.header.unit].atx_leds = resp.body
|
||||
self.__queue_event(UnitAtxLedsEvent(resp.header.unit, resp.body))
|
||||
|
||||
def __adjust_quirks(self) -> None:
|
||||
for (unit, ctx) in enumerate(self.__units):
|
||||
if ctx.state is not None and (ctx.state.version.sw_dev or ctx.state.version.sw >= 7):
|
||||
ignore_hpd = (unit == 0 and self.__ignore_hpd_on_top)
|
||||
if ctx.state.quirks.ignore_hpd != ignore_hpd:
|
||||
get_logger().info("Applying quirk ignore_hpd=%s to [%d] ...",
|
||||
ignore_hpd, unit)
|
||||
self.__device.request_set_quirks(unit, ignore_hpd)
|
||||
|
||||
def __adjust_start_port(self) -> None:
|
||||
if self.__active_port < 0:
|
||||
for (unit, ctx) in enumerate(self.__units):
|
||||
|
||||
@ -42,6 +42,7 @@ from .proto import BodyAtxClick
|
||||
from .proto import BodySetEdid
|
||||
from .proto import BodyClearEdid
|
||||
from .proto import BodySetColors
|
||||
from .proto import BodySetQuirks
|
||||
|
||||
|
||||
# =====
|
||||
@ -166,6 +167,9 @@ class Device:
|
||||
def request_set_colors(self, unit: int, ch: int, colors: Colors) -> int:
|
||||
return self.__send_request(Header.SET_COLORS, unit, BodySetColors(ch, colors))
|
||||
|
||||
def request_set_quirks(self, unit: int, ignore_hpd: bool) -> int:
|
||||
return self.__send_request(Header.SET_QUIRKS, unit, BodySetQuirks(ignore_hpd))
|
||||
|
||||
def __send_request(self, op: int, unit: int, body: (Packable | None)) -> int:
|
||||
assert self.__tty is not None
|
||||
req = Request(Header(
|
||||
|
||||
@ -60,6 +60,7 @@ class Header(Packable, Unpackable):
|
||||
SET_EDID = 9
|
||||
CLEAR_EDID = 10
|
||||
SET_COLORS = 12
|
||||
SET_QUIRKS = 13
|
||||
|
||||
__struct = struct.Struct("<BHBB")
|
||||
|
||||
@ -89,6 +90,13 @@ class Nak(Unpackable):
|
||||
return Nak(*cls.__struct.unpack_from(data, offset=offset))
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class UnitVersion:
|
||||
hw: int
|
||||
sw: int
|
||||
sw_dev: bool
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class UnitFlags:
|
||||
changing_busy: bool
|
||||
@ -97,10 +105,14 @@ class UnitFlags:
|
||||
has_hpd: bool
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class UnitQuirks:
|
||||
ignore_hpd: bool
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class UnitState(Unpackable): # pylint: disable=too-many-instance-attributes
|
||||
sw_version: int
|
||||
hw_version: int
|
||||
version: UnitVersion
|
||||
flags: UnitFlags
|
||||
ch: int
|
||||
beacons: tuple[bool, bool, bool, bool, bool, bool]
|
||||
@ -111,8 +123,9 @@ class UnitState(Unpackable): # pylint: disable=too-many-instance-attributes
|
||||
video_crc: tuple[int, int, int, int]
|
||||
usb_5v_sens: tuple[bool, bool, bool, bool]
|
||||
atx_busy: tuple[bool, bool, bool, bool]
|
||||
quirks: UnitQuirks
|
||||
|
||||
__struct = struct.Struct("<HHHBBHHHHHHBBBHHHHBxB30x")
|
||||
__struct = struct.Struct("<HHHBBHHHHHHBBBHHHHBxBB29x")
|
||||
|
||||
def compare_edid(self, ch: int, edid: Optional["Edid"]) -> bool:
|
||||
if edid is None:
|
||||
@ -129,11 +142,14 @@ class UnitState(Unpackable): # pylint: disable=too-many-instance-attributes
|
||||
sw_version, hw_version, flags, ch,
|
||||
beacons, nc0, nc1, nc2, nc3, nc4, nc5,
|
||||
video_5v_sens, video_hpd, video_edid, vc0, vc1, vc2, vc3,
|
||||
usb_5v_sens, atx_busy,
|
||||
usb_5v_sens, atx_busy, quirks,
|
||||
) = cls.__struct.unpack_from(data, offset=offset)
|
||||
return UnitState(
|
||||
sw_version,
|
||||
hw_version,
|
||||
version=UnitVersion(
|
||||
hw=hw_version,
|
||||
sw=(sw_version & 0x7FFF),
|
||||
sw_dev=bool(sw_version & 0x8000),
|
||||
),
|
||||
flags=UnitFlags(
|
||||
changing_busy=bool(flags & 0x80),
|
||||
flashing_busy=bool(flags & 0x40),
|
||||
@ -149,6 +165,7 @@ class UnitState(Unpackable): # pylint: disable=too-many-instance-attributes
|
||||
video_crc=(vc0, vc1, vc2, vc3),
|
||||
usb_5v_sens=cls.__make_flags4(usb_5v_sens),
|
||||
atx_busy=cls.__make_flags4(atx_busy),
|
||||
quirks=UnitQuirks(ignore_hpd=bool(quirks & 0x01)),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -265,6 +282,14 @@ class BodySetColors(Packable):
|
||||
return self.ch.to_bytes() + self.colors.pack()
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class BodySetQuirks(Packable):
|
||||
ignore_hpd: bool
|
||||
|
||||
def pack(self) -> bytes:
|
||||
return self.ignore_hpd.to_bytes()
|
||||
|
||||
|
||||
# =====
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class Request:
|
||||
|
||||
@ -49,7 +49,7 @@ class _UnitInfo:
|
||||
|
||||
# =====
|
||||
class StateCache: # pylint: disable=too-many-instance-attributes
|
||||
__FW_VERSION = 6
|
||||
__FW_VERSION = 7
|
||||
|
||||
__FULL = 0xFFFF
|
||||
__SUMMARY = 0x01
|
||||
@ -195,7 +195,10 @@ class StateCache: # pylint: disable=too-many-instance-attributes
|
||||
assert ui.state is not None
|
||||
assert ui.atx_leds is not None
|
||||
if x_model:
|
||||
state["model"]["units"].append({"firmware": {"version": ui.state.sw_version}})
|
||||
state["model"]["units"].append({"firmware": {
|
||||
"version": ui.state.version.sw,
|
||||
"devbuild": ui.state.version.sw_dev,
|
||||
}})
|
||||
if x_video:
|
||||
state["video"]["links"].extend(ui.state.video_5v_sens[:4])
|
||||
if x_usb:
|
||||
|
||||
Binary file not shown.
@ -408,7 +408,8 @@ export function Switch() {
|
||||
$("switch-chain").innerHTML = content;
|
||||
|
||||
if (model.units.length > 0) {
|
||||
tools.hidden.setVisible($("switch-message-update"), (model.firmware.version > model.units[0].firmware.version));
|
||||
let fw = model.units[0].firmware;
|
||||
tools.hidden.setVisible($("switch-message-update"), (fw.devbuild || fw.version < model.firmware.version));
|
||||
}
|
||||
|
||||
for (let unit = 0; unit < model.units.length; ++unit) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user