diff --git a/service/usbip/host_linux.go b/service/usbip/host_linux.go index b9d7e915c..fdcc989ef 100644 --- a/service/usbip/host_linux.go +++ b/service/usbip/host_linux.go @@ -741,26 +741,25 @@ func (h *linuxImportHost) Attach(ctx context.Context, info DeviceInfoTruncated, mode = "relay" } h.logger.Debug("usbip client handoff ", info.BusIDString(), ": ", mode) - port, secondary, attachErr := h.attachOnce(ctx, info, handoff) + port, attachErr := h.attachOnce(ctx, info, handoff) if attachErr != nil { _ = handoff.Close() return nil, attachErr } _ = handoff.Start() return &linuxClientSession{ - handoff: handoff, - host: h, - port: port, - secondary: secondary, + handoff: handoff, + host: h, + port: port, }, nil } -func (h *linuxImportHost) attachOnce(ctx context.Context, info DeviceInfoTruncated, handoff *kernelHandoffSession) (int, int, error) { +func (h *linuxImportHost) attachOnce(ctx context.Context, info DeviceInfoTruncated, handoff *kernelHandoffSession) (int, error) { triedPorts := make(map[int]struct{}) for { port, err := vhciPickFreePort(info.Speed, triedPorts) if err != nil { - return -1, 0, err + return -1, err } if !h.reservePort(port) { triedPorts[port] = struct{}{} @@ -774,29 +773,16 @@ func (h *linuxImportHost) attachOnce(ctx context.Context, info DeviceInfoTruncat triedPorts[port] = struct{}{} continue } - return -1, 0, E.Cause(err, "vhci attach") + return -1, E.Cause(err, "vhci attach") } err = handoff.closeKernelFD() if err != nil { h.logger.Debug("close kernel fd ", info.BusIDString(), ": ", err) } - return port, lookupSecondaryForPort(port), nil + return port, nil } } -func lookupSecondaryForPort(port int) int { - records, err := readPrimaryVHCIStatus() - if err != nil { - return 0 - } - for _, record := range records { - if record.port == port { - return record.secondary - } - } - return 0 -} - func (h *linuxImportHost) reservePort(port int) bool { h.portsAccess.Lock() defer h.portsAccess.Unlock() @@ -818,10 +804,9 @@ func (h *linuxImportHost) releasePort(port int) { } type linuxClientSession struct { - handoff *kernelHandoffSession - host *linuxImportHost - port int - secondary int + handoff *kernelHandoffSession + host *linuxImportHost + port int closeOnce sync.Once closeErr error @@ -850,8 +835,5 @@ func (s *linuxClientSession) Close() error { } func (s *linuxClientSession) Description() string { - if s.secondary == 0 { - return fmt.Sprintf("vhci_hcd.0 port %d", s.port) - } - return fmt.Sprintf("vhci_hcd.0 (controller %d) port %d", s.secondary, s.port) + return fmt.Sprintf("vhci_hcd.0 port %d", s.port) } diff --git a/service/usbip/sysfs_linux.go b/service/usbip/sysfs_linux.go index 7595f654e..d3aa6dbfa 100644 --- a/service/usbip/sysfs_linux.go +++ b/service/usbip/sysfs_linux.go @@ -68,13 +68,11 @@ func (d *sysfsDevice) toProtocol() DeviceInfoTruncated { // vhciStatusRecord is one row of /sys/devices/platform/vhci_hcd.0/status // or status.N. The kernel emits globally unique port numbers across every -// status* file; secondary identifies which file the row came from -// (0 for status, N for status.N) and exists only for diagnostic logging. +// status* file. type vhciStatusRecord struct { - secondary int - hub string - port int - state int + hub string + port int + state int } func listUSBDevices() ([]sysfsDevice, error) { @@ -213,8 +211,8 @@ func waitForUsbipStatusCleared(ctx context.Context, busid string) { // readPrimaryVHCIStatus reads every status* file under // /sys/devices/platform/vhci_hcd.0 and concatenates the rows in lexical -// order. status reports controller 0; status.N reports controller N. -// Port numbers are already globally unique — no remapping is needed. +// order. Port numbers are already globally unique across controllers — no +// remapping is needed. func readPrimaryVHCIStatus() ([]vhciStatusRecord, error) { matches, err := filepath.Glob(filepath.Join(sysVHCIControllerV0, "status*")) if err != nil { @@ -223,15 +221,15 @@ func readPrimaryVHCIStatus() ([]vhciStatusRecord, error) { sort.Strings(matches) records := make([]vhciStatusRecord, 0) for _, path := range matches { - secondary, parseErr := vhciSecondaryFromStatusFile(filepath.Base(path)) - if parseErr != nil { + base := filepath.Base(path) + if base != "status" && !strings.HasPrefix(base, "status.") { continue } raw, readErr := os.ReadFile(path) if readErr != nil { return nil, readErr } - records = append(records, parseVHCIStatus(secondary, string(raw))...) + records = append(records, parseVHCIStatus(string(raw))...) } return records, nil } @@ -267,18 +265,7 @@ func vhciPickFreePort(speed uint32, skip map[int]struct{}) (int, error) { return -1, E.New("no free ", targetHub, " vhci port") } -func vhciSecondaryFromStatusFile(name string) (int, error) { - if name == "status" { - return 0, nil - } - suffix := strings.TrimPrefix(name, "status.") - if suffix == name { - return 0, E.New("not a status file: ", name) - } - return strconv.Atoi(suffix) -} - -func parseVHCIStatus(secondary int, raw string) []vhciStatusRecord { +func parseVHCIStatus(raw string) []vhciStatusRecord { scanner := bufio.NewScanner(strings.NewReader(raw)) records := make([]vhciStatusRecord, 0) first := true @@ -304,10 +291,9 @@ func parseVHCIStatus(secondary int, raw string) []vhciStatusRecord { continue } records = append(records, vhciStatusRecord{ - secondary: secondary, - hub: fields[0], - port: port, - state: state, + hub: fields[0], + port: port, + state: state, }) } return records