fix keyboard and mass storgae stream
This commit is contained in:
parent
67ab5418ee
commit
3a94bf35a7
BIN
bin/usb-client
BIN
bin/usb-client
Binary file not shown.
Binary file not shown.
BIN
bin/usb-relay
BIN
bin/usb-relay
Binary file not shown.
|
|
@ -37,6 +37,7 @@ var (
|
|||
usbdevfsSetInterface = ior('U', 4, unsafe.Sizeof(usbdevfsSetIntf{}))
|
||||
usbdevfsSetConfig = ior('U', 5, 4)
|
||||
usbdevfsSubmitURB = ior('U', 10, unsafe.Sizeof(usbdevfsURB{}))
|
||||
usbdevfsResetEP = ior('U', 3, 4)
|
||||
usbdevfsDiscardURB = io_('U', 11)
|
||||
usbdevfsReapURB = iow('U', 12, unsafe.Sizeof(uintptr(0)))
|
||||
usbdevfsReapURBNDelay = iow('U', 13, unsafe.Sizeof(uintptr(0)))
|
||||
|
|
@ -348,6 +349,27 @@ func (h *DeviceHandle) DiscardURB(urb *usbdevfsURB) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// DiscardURBByPtr cancels a submitted URB given its raw pointer.
|
||||
// Use this when the URB type is not accessible (e.g. from another package).
|
||||
func (h *DeviceHandle) DiscardURBByPtr(ptr unsafe.Pointer) error {
|
||||
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(h.fd), usbdevfsDiscardURB, uintptr(ptr))
|
||||
if errno != 0 {
|
||||
return fmt.Errorf("USBDEVFS_DISCARDURB: %w", errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResetEndpoint resets the host-side data toggle for an endpoint without
|
||||
// sending any USB traffic to the device. Use after SET_CONFIGURATION to
|
||||
// sync host controller toggle state with the device.
|
||||
func (h *DeviceHandle) ResetEndpoint(endpoint uint32) error {
|
||||
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(h.fd), usbdevfsResetEP, uintptr(unsafe.Pointer(&endpoint)))
|
||||
if errno != 0 {
|
||||
return fmt.Errorf("USBDEVFS_RESETEP(%d): %w", endpoint, errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SubmitISOURBParams holds parameters for async ISO URB submission
|
||||
type SubmitISOURBParams struct {
|
||||
Endpoint uint8
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import (
|
|||
"unsafe"
|
||||
|
||||
"github.com/duffy/usb-server/internal/usb"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Server handles USB/IP protocol on the share side.
|
||||
|
|
@ -112,9 +111,7 @@ func (s *Server) Detach() {
|
|||
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))
|
||||
s.handle.DiscardURBByPtr(pending.urbPtr)
|
||||
}
|
||||
delete(s.pendingURBs, seqNum)
|
||||
}
|
||||
|
|
@ -410,6 +407,33 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||
status = -32
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
// Generic OUT control transfer
|
||||
buf := transferBuf
|
||||
|
|
@ -577,11 +601,7 @@ func (s *Server) handleCmdUnlink(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||
|
||||
var status int32
|
||||
if exists && pending.urbPtr != nil {
|
||||
// Try to discard the URB via proper ioctl
|
||||
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(s.handle.Fd()),
|
||||
uintptr(0x8000550B), // USBDEVFS_DISCARDURB
|
||||
uintptr(pending.urbPtr))
|
||||
if errno == 0 {
|
||||
if err := s.handle.DiscardURBByPtr(pending.urbPtr); err == nil {
|
||||
status = -104 // -ECONNRESET
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue