Golang, GoUSB, Device detach: USBInterfaceOpen: another process has device opened for exclusive access

Viewed 472

I am trying to implement the simplest driver and I can't do a device detach, although I set an automatic detach. Maybe someone will have ideas about what the problem is. I use MacOS Big Sur.

package main

import (
    "flag"
    "fmt"
    "log"

    "github.com/google/gousb"
)

var (
    debug = flag.Int("debug", 0, "libusb debug level (0..3)")
)

func main() {
    flag.Parse()

    // Initialize a new Context.
    ctx := gousb.NewContext()
    defer ctx.Close()

    ctx.Debug(4)

    vid, pid := gousb.ID(0x0079), gousb.ID(0x0011)
    devs, err := ctx.OpenDevices(func(desc *gousb.DeviceDesc) bool {
        return desc.Vendor == vid && desc.Product == pid
    })
    // All returned devices are now open and will need to be closed.
    for _, d := range devs {
        defer d.Close()
    }
    if err != nil {
        log.Fatalf("OpenDevices(): %v", err)
    }
    if len(devs) == 0 {
        log.Fatalf("no devices found matching VID %s and PID %s", vid, pid)
    }

    // Pick the first device found.
    dev := devs[0]

    // Here i am trying to set up detach
    err = dev.SetAutoDetach(true)
    if err != nil {
        log.Fatalf("%s.SetAutoDetach(true): %v", dev, err)
    }

    // Because of SetAutoDetach() it runs this part of code:
    // https://github.com/google/gousb/blob/master/device.go#L151
    // but for some reason it doesn't work for me
    cfg, err := dev.Config(1)
    if err != nil {
        log.Fatalf("%s.Config(2): %v", dev, err)
    }
    defer cfg.Close()

    // In the config #1, claim interface #0 with alt setting #0.
    intf, err := cfg.Interface(0, 0)
    if err != nil {
        log.Fatalf("%s.Interface(0, 0): %v", cfg, err)
    }
    defer intf.Close()

    fmt.Println(intf)

}

Despite the SetAutoDetach(true), I get the error:

$ go run .                                                                                                                                             [timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
[ 0.015613] [008aa6b3] libusb: debug [libusb_get_device_list]
[ 0.015561] [008aa6ca] libusb: debug [libusb_get_next_timeout] no URBs, no timeout!
[ 0.015648] [008aa6b3] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.015662] [008aa6ca] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.015681] [008aa6ca] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.015690] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.015706] [008aa6ca] libusb: debug [usbi_wait_for_events] poll() 1 fds with timeout in 100ms
[ 0.015718] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.015755] [008aa6b3] libusb: debug [libusb_open] open 20.47
[ 0.015881] [008aa6b3] libusb: debug [darwin_open] device open for access
[ 0.015917] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.015933] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.015949] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.015963] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.015977] [008aa6b3] libusb: debug [parse_endpoint] skipping descriptor 0x30
[ 0.016010] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.016037] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.016080] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.016098] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.016111] [008aa6b3] libusb: debug [parse_endpoint] skipping descriptor 0x30
[ 0.016127] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.016138] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.016151] [008aa6b3] libusb: debug [parse_endpoint] skipping descriptor 0x30
[ 0.016165] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.016177] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.016194] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.016207] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.016226] [008aa6b3] libusb: debug [libusb_get_device_descriptor]
[ 0.016238] [008aa6b3] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.016278] [008aa6b3] libusb: debug [libusb_detach_kernel_driver] interface 0
[ 0.016296] [008aa6b3] libusb: debug [libusb_get_configuration]
[ 0.016307] [008aa6b3] libusb: debug [libusb_get_configuration] active config 1
[ 0.016324] [008aa6b3] libusb: debug [libusb_claim_interface] interface 0
[ 0.017210] [008aa6b3] libusb: error [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
2021/03/23 23:42:02 vid=0079,pid=0011,bus=20,addr=47,config=1.Interface(0, 0): failed to claim interface 0 on vid=0079,pid=0011,bus=20,addr=47,config=1: libusb: bad access [code -3]
exit status 1

And this is my USB stack. I'm trying to connect to USB Gamepad using USB-A to USB-C adapter because I don't have USB-A on this laptop. However, this may be the problem. But in this case, the question remains, how to get around this?

    USB 3.0 Bus:

      Host Controller Driver: AppleUSBXHCISPT
      PCI Device ID: 0xa12f
      PCI Revision ID: 0x0031
      PCI Vendor ID: 0x8086

        USB2.0 Hub:

          Product ID: 0x100f
          Vendor ID: 0x05ac (Apple Inc.)
          Version: 45.28
          Speed: Up to 480 Mb/s
          Manufacturer: Apple Inc.
          Location ID: 0x14500000 / 45
          Current Available (mA): 500
          Current Required (mA): 100
          Extra Operating Current (mA): 0

            USB Gamepad :

              Product ID: 0x0011
              Vendor ID: 0x0079
              Version: 1.06
              Speed: Up to 1.5 Mb/s
              Location ID: 0x14510000 / 47
              Current Available (mA): 500
              Current Required (mA): 100
              Extra Operating Current (mA): 0
0 Answers
Related