google / gousb

gousb provides low-level interface for accessing USB devices
Apache License 2.0
838 stars 124 forks source link

Device detach: libusb: error [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access #95

Closed memowiki closed 3 years ago

memowiki commented 3 years ago

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
zagrodzki commented 3 years ago

This is not the right forum for this question, since your problem doesn't seem to be caused by gousb. You can see that gousb correctly invokes libusb_detach_kernel_driver in your debug log, the rest depends on your system and software that you have running concurrently.

memowiki commented 3 years ago

I understand that the gousb performs detach, but apparently, this is not enough or it does it not for what is needed. For me, the problem looks like - gousb detach does not work properly on the Darwin platform in some cases. And I think it makes sense to find out what these cases are and fix them. Unfortunately, I do not have such deep knowledge in this to get to the bottom of the error on my own. So I gave an example of the simplest script that consists exclusively of gousb functions. Here literally, there are no functions from other external libraries. And that doesn't work for Darwin, although such support is stated. I don't understand which forum should I go to with a script that consists exclusively of gousb functions?

zagrodzki commented 3 years ago

I don't have an answer to your question. All I can say is that gousb seems to be behaving as intended.