diff --git a/bin/usb-client b/bin/usb-client index 41d28ae..935aac9 100755 Binary files a/bin/usb-client and b/bin/usb-client differ diff --git a/bin/usb-client.exe b/bin/usb-client.exe index cfa0759..b5b1d92 100755 Binary files a/bin/usb-client.exe and b/bin/usb-client.exe differ diff --git a/bin/usb-relay b/bin/usb-relay index 7bbbd7e..1324538 100755 Binary files a/bin/usb-relay and b/bin/usb-relay differ diff --git a/internal/usbip/server.go b/internal/usbip/server.go index cf9cdcb..13c68fb 100644 --- a/internal/usbip/server.go +++ b/internal/usbip/server.go @@ -408,30 +408,21 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b } case bmRequestType == 0x00 && bRequest == 0x09: - // SET_CONFIGURATION — the device resets all endpoint data toggles - // to DATA0 on SET_CONFIGURATION, but USBDEVFS_CONTROL doesn't update - // the host controller's toggle state. We must manually reset host-side - // toggles via USBDEVFS_RESETEP, otherwise data toggle mismatch causes - // all non-control transfers (bulk, interrupt) to fail silently. - buf := transferBuf - if buf == nil { - buf = make([]byte, 0) - } - _, err := s.handle.ControlTransfer(bmRequestType, bRequest, wValue, wIndex, 0, 5000, buf) - if err != nil { - log.Printf("[usbip-server] SET_CONFIGURATION(%d) failed: %v", wValue, err) - status = -32 - } else { - log.Printf("[usbip-server] SET_CONFIGURATION(%d) OK, resetting endpoint toggles", wValue) - for epNum := range s.epTypes { - if epNum == 0 { - continue - } - // Reset both OUT and IN directions; ignore errors for - // non-existent directions (e.g. endpoint only has IN) - s.handle.ResetEndpoint(uint32(epNum)) - s.handle.ResetEndpoint(uint32(epNum) | 0x80) + // SET_CONFIGURATION — do NOT forward to the physical device. + // The device is already configured (we claimed interfaces during Attach). + // Sending SET_CONFIGURATION via raw USBDEVFS_CONTROL would reset the + // device's endpoint state without updating the kernel's internal USB + // subsystem, breaking all subsequent SETINTERFACE and SUBMITURB calls + // (ESRCH / EHOSTUNREACH). + // Just reset host-side data toggles to DATA0 (matching the fresh VHCI + // state on the use-side) and return success. + log.Printf("[usbip-server] SET_CONFIGURATION(%d) intercepted (device already configured), resetting endpoint toggles", wValue) + for epNum := range s.epTypes { + if epNum == 0 { + continue } + s.handle.ResetEndpoint(uint32(epNum)) + s.handle.ResetEndpoint(uint32(epNum) | 0x80) } default: