fix detach function with usb reset

This commit is contained in:
duffyduck 2026-02-18 22:53:39 +01:00
parent 99d9242264
commit cc1dfff382
3 changed files with 32 additions and 4 deletions

Binary file not shown.

Binary file not shown.

View File

@ -105,14 +105,42 @@ func (s *Server) Detach() {
return
}
// Release all interfaces
// 1. Discard all pending URBs to clean up device state
s.mu.Lock()
for seqNum, pending := range s.pendingURBs {
if pending.urbPtr != nil {
unix.Syscall(unix.SYS_IOCTL, uintptr(s.handle.Fd()),
0x8000550B, // USBDEVFS_DISCARDURB
uintptr(pending.urbPtr))
}
delete(s.pendingURBs, seqNum)
}
s.mu.Unlock()
// 2. Release all claimed interfaces
for _, iface := range s.device.Interfaces {
s.handle.ReleaseInterface(uint32(iface.Number))
if err := s.handle.ReleaseInterface(uint32(iface.Number)); err != nil {
log.Printf("[usbip-server] release interface %d: %v", iface.Number, err)
}
}
// Reconnect kernel driver
s.handle.ConnectDriver()
// 3. Reset device to force driver re-probing (most reliable method)
// A USB reset forces the kernel to re-enumerate and rebind drivers.
// This is important for devices like webcams that may be left in a
// streaming state after URB transfers.
if err := s.handle.ResetDevice(); err != nil {
log.Printf("[usbip-server] device reset failed: %v, trying ConnectDriver", err)
// Fallback: try to reconnect kernel driver without reset
if err := s.handle.ConnectDriver(); err != nil {
log.Printf("[usbip-server] ConnectDriver also failed: %v", err)
} else {
log.Printf("[usbip-server] kernel driver reconnected via ConnectDriver")
}
} else {
log.Printf("[usbip-server] device reset OK, kernel drivers re-bound")
}
// 4. Close the device file descriptor
s.handle.Close()
s.handle = nil
}