IOUSBInterfaceOpen 失败,但我可以通过卸载相机来让它工作……这是怎么回事?

IOUSBInterfaceOpen fails, but I can get it to work by unmounting the camera... What's going on?

我正在尝试为 MacO 编写一个 Pentax 相机 USB 驱动程序,但没有太多经验。我已经能够使用 "Working with USB Device Interfaces" 中的示例代码与相机通信,但前提是我使用异步通知并且弹出并重新连接相机。如果在调试期间,代码在安装相机之前捕获相机,它似乎可以工作。我想在没有通知和 CF​​Runloop 的情况下执行此操作,所以我现在尝试使用 IOServiceGetMatchingServices()。我可以获取设备、配置、执行 DeviceRequest 甚至创建设备接口,获取它 class 但 USBInterfaceOpen 失败。我想我需要设置一个到端点之一的管道,以便 DeviceRequest 的工作不仅仅是获取状态,但我无法打开界面。谢谢

编辑:

所以在我看来,唯一的接口是 IOUSBHostInterface@0,这是用于大容量存储访问,对吗?所以我想尝试使用 DeviceRequest 发送命令 - 到我认为的控制界面 - 是唯一的选择,但失败并显示错误代码 e000404f。我相信我可以正确地制定命令,因为我可以在 Wireshark 中看到字节,但整个数据包与我在 PC USB 上看到的不一样。也许我还没有得到正确的命令字节?

+-o K-5 II@14200000  <class IORegistryEntry:IOService:IOUSBNub:IOUSBDevice, id 0x100002645, registered, matched, active, busy 0 (2976 ms), retai$
  | {
  |   "sessionID" = 116428207269670
  |   "USBSpeed" = 3
  |   "IOServiceLegacyMatchingRegistryID" = 4294977095
  |   "idProduct" = 328
  |   "bDeviceClass" = 0
  |   "IOPowerManagement" = {"PowerOverrideOn"=Yes,"CapabilityFlags"=32768,"MaxPowerState"=2,"DevicePowerState"=2,"ChildrenPowerState"=2,"Driver$
  |   "bcdDevice" = 263
  |   "USB Product Name" = "K-5 II"
  |   "AppleUSBAlternateServiceRegistryID" = 4294977095
  |   "locationID" = 337641472
  |   "kUSBSerialNumberString" = "4585468"
  |   "bDeviceSubClass" = 0
  |   "kUSBCurrentConfiguration" = 1
  |   "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
  |   "bDeviceProtocol" = 0
  |   "USBPortType" = 0
  |   "USB Vendor Name" = "PENTAX"
  |   "idVendor" = 9723
  |   "USB Serial Number" = "4585468"
  |   "IOGeneralInterest" = "IOCommand is not serializable"
  |   "kUSBVendorString" = "PENTAX"
  |   "IOClassNameOverride" = "IOUSBDevice"
  | }
  | 
  +-o AppleUSBHostLegacyClient  <class IORegistryEntry:IOService:AppleUSBHostLegacyClient, id 0x100002648, !registered, !matched, active, busy 0$
  |   {
  |     "IOPowerManagement" = {"DevicePowerState"=0,"CurrentPowerState"=1,"CapabilityFlags"=65536,"MaxPowerState"=2,"DriverPowerState"=1}
  |   }
  |   
  +-o AppleUSBHostCompositeDevice  <class IORegistryEntry:IOService:AppleUSBHostCompositeDevice, id 0x100002650, !registered, !matched, active, $
  |   {
  |     "IOProbeScore" = 50000
  |     "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBHostCompositeDevice"
  |     "IOProviderClass" = "IOUSBHostDevice"
  |     "IOClass" = "AppleUSBHostCompositeDevice"
  |     "bDeviceSubClass" = 0
  |     "IOMatchCategory" = "IODefaultMatchCategory"
  |     "kUSBPreferredConfiguration" = 1
  |     "bDeviceClass" = 0
  |   }
  |   
  +-o IOUSBHostInterface@0  <class IORegistryEntry:IOService:IOUSBNub:IOUSBInterface, id 0x100002652, registered, matched, active, busy 0 (1112 $
    | {
    |   "USBPortType" = 0
    |   "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    |   "bcdDevice" = 263
    |   "USBSpeed" = 3
    |   "idProduct" = 328
    |   "bConfigurationValue" = 1
    |   "bInterfaceSubClass" = 6
    |   "locationID" = 337641472
    |   "IOGeneralInterest" = "IOCommand is not serializable"
    |   "IOServiceLegacyMatchingRegistryID" = 4294977107
    |   "IOClassNameOverride" = "IOUSBInterface"
    |   "AppleUSBAlternateServiceRegistryID" = 4294977107
    |   "idVendor" = 9723
    |   "bInterfaceProtocol" = 80
    |   "bAlternateSetting" = 0
    |   "bInterfaceNumber" = 0
    |   "bInterfaceClass" = 8
    | }
    | 
    +-o IOUSBMassStorageInterfaceNub  <class IORegistryEntry:IOService:IOUSBMassStorageInterfaceNub, id 0x100002654, registered, matched, active$
      | {
      |   "IOClass" = "IOUSBMassStorageInterfaceNub"
      |   "idProduct" = 328
      |   "bInterfaceProtocol" = 80
      |   "USB Device Info" = {"bcdDevice"=263,"idProduct"=328,"kUSBVendorString"="PENTAX","bConfigurationValue"=1,"kUSBSerialNumberString"="458$
      |   "bcdDevice" = 263
      |   "IOProviderClass" = "IOUSBHostInterface"
      |   "Physical Interconnect Location" = "External"
      |   "USB Product Name" = "K-5 II"
      |   "IOPowerManagement" = {"DevicePowerState"=1,"CurrentPowerState"=1,"CapabilityFlags"=32768,"MaxPowerState"=1,"DriverPowerState"=1}
      |   "IOProbeScore" = 50000
      |   "locationID" = 337641472
      |   "kUSBSerialNumberString" = "4585468"
      |   "bInterfaceSubClass" = 6
      |   "bInterfaceClass" = 8
      |   "Physical Interconnect" = "USB"
      |   "bConfigurationValue" = 1
      |   "IOMatchCategory" = "IODefaultMatchCategory"
      |   "CFBundleIdentifier" = "com.apple.iokit.IOUSBMassStorageDriver"
      |   "bInterfaceNumber" = 0
      |   "idVendor" = 9723
      |   "USB Mass Storage Trace ID" = 2736782607644622848
      |   "kUSBVendorString" = "PENTAX"
      | }
      | 
      +-o IOUSBMassStorageDriverNub  <class IORegistryEntry:IOService:IOUSBMassStorageDriverNub, id 0x100002656, registered, matched, active, bu$
        | {
        |   "IOClass" = "IOUSBMassStorageDriverNub"
        |   "CFBundleIdentifier" = "com.apple.iokit.IOUSBMassStorageDriver"
        |   "IOProviderClass" = "IOUSBMassStorageInterfaceNub"
        |   "USB Mass Storage Trace ID" = 2736782607644622848
        |   "IOPowerManagement" = {"ChildrenPowerState"=1,"DevicePowerState"=1,"CurrentPowerState"=1,"CapabilityFlags"=32768,"MaxPowerState"=1,"$
        |   "idProduct" = 328
        |   "IOProbeScore" = 0
        |   "bConfigurationValue" = 1
        |   "bInterfaceSubClass" = 6
        |   "IOMatchCategory" = "IODefaultMatchCategory"
        |   "kUSBVendorString" = "PENTAX"
        |   "USB Product Name" = "K-5 II"
        |   "USB Device Info" = {"bcdDevice"=263,"idProduct"=328,"kUSBVendorString"="PENTAX","bConfigurationValue"=1,"kUSBSerialNumberString"="4$
        |   "Physical Interconnect" = "USB"
        |   "idVendor" = 9723
        |   "bInterfaceProtocol" = 80
        |   "Physical Interconnect Location" = "External"
        |   "bInterfaceNumber" = 0
        |   "bInterfaceClass" = 8
        | }
        | 
        +-o IOUSBMassStorageDriver  <class IORegistryEntry:IOService:IOSCSIProtocolInterface:IOSCSIProtocolServices:IOUSBMassStorageDriver, id 0$
          | {
          |   "IOClass" = "IOUSBMassStorageDriver"
          |   "CFBundleIdentifier" = "com.apple.iokit.IOUSBMassStorageDriver"
          |   "IOProviderClass" = "IOUSBMassStorageDriverNub"
          |   "Write Time Out Duration" = 30000
          |   "USB Mass Storage Trace ID" = 2736782607644622848
          |   "IOPowerManagement" = {"ChildrenPowerState"=1,"DevicePowerState"=1,"CurrentPowerState"=1,"CapabilityFlags"=32768,"MaxPowerState"=1$
          |   "Read Time Out Duration" = 30000
          |   "IOProbeScore" = 0
          |   "IOUnit" = 16
          |   "IOMatchCategory" = "IODefaultMatchCategory"
          |   "Retry Count" = 20
          |   "Protocol Characteristics" = {"Physical Interconnect"="USB","Read Time Out Duration"=30000,"Physical Interconnect Location"="Exter$
          |   "bInterfaceProtocol" = 80
          |   "Physical Interconnect Location" = "External"
          |   "No INQUIRY VPD Pages" = Yes
          | }
          | 
          +-o IOSCSILogicalUnitNub@0  <class IORegistryEntry:IOService:IOSCSIProtocolInterface:IOSCSIProtocolServices:IOSCSIPeripheralDeviceNub:$
            | {
            |   "TPGS Information" = 0
            |   "Peripheral Device Type" = 0
            |   "Vendor Identification" = "PENTAX"
            |   "SCSI Logical Unit Number" = 0
            |   "IOMatchCategory" = "SCSITaskUserClientIniter"
            |   "Product Identification" = "DSC_K-5_II"
            |   "Protocol Characteristics" = {"Physical Interconnect"="USB","Read Time Out Duration"=30000,"SCSI Logical Unit Number"=0,"Physica$
            |   "IOUnitLUN" = 0
            |   "Product Revision Level" = "1.07"
            | }
            | 
            +-o IOSCSIPeripheralDeviceType00  <class IORegistryEntry:IOService:IOSCSIProtocolInterface:IOSCSIPrimaryCommandsDevice:IOSCSIBlockCo$
              | {
              |   "IOClass" = "IOSCSIPeripheralDeviceType00"
              |   "CFBundleIdentifier" = "com.apple.iokit.IOSCSIBlockCommandsDevice"
              |   "IOProviderClass" = "IOSCSIPeripheralDeviceNub"
              |   "IOMaximumBlockCountRead" = 256
              |   "IOPowerManagement" = {"CapabilityFlags"=49216,"MaxPowerState"=4,"ActivityTickles"=58,"IdleTimerPeriod"=200000,"DevicePowerSta$
              |   "IOMaximumBlockCountWrite" = 256
              |   "IOProbeScore" = 5000
              |   "Peripheral Device Type" = 0
              |   "IOMatchCategory" = "IODefaultMatchCategory"
              |   "IOMaximumByteCountWrite" = 131072
              |   "WriteCacheState" = No
              |   "IOMaximumByteCountRead" = 131072
              | }
              | 
              +-o IOBlockStorageServices  <class IORegistryEntry:IOService:IOBlockStorageDevice:IOBlockStorageServices, id 0x100002660, register$
                | {
                |   "IOMinimumSegmentAlignmentByteCount" = 4
                |   "device-type" = "Generic"
                |   "Device Characteristics" = {"Vendor Name"="PENTAX","Product Name"="DSC_K-5_II","Product Revision Level"="1.07"}
                |   "Protocol Characteristics" = {"Physical Interconnect"="USB","Read Time Out Duration"=30000,"SCSI Logical Unit Number"=0,"Phy$
                | }
                | 
                +-o IOBlockStorageDriver  <class IORegistryEntry:IOService:IOStorage:IOBlockStorageDriver, id 0x100002661, registered, matched, $
                  | {
                  |   "IOPropertyMatch" = {"device-type"="Generic"}
                  |   "IOProbeScore" = 0
                  |   "IOProviderClass" = "IOBlockStorageDevice"
                  |   "IOClass" = "IOBlockStorageDriver"
                  |   "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                  |   "Statistics" = {"Operations (Write)"=6,"Latency Time (Write)"=0,"Bytes (Read)"=2269184,"Errors (Write)"=0,"Total Time (Rea$
                  |   "IOMatchCategory" = "IODefaultMatchCategory"
                  |   "IOGeneralInterest" = "IOCommand is not serializable"
                  | }
                  | 
                  +-o PENTAX DSC_K-5_II Media  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x100002664, registered, matched, active, $
                    | {
                    |   "Removable" = Yes
                    |   "Content" = "FDisk_partition_scheme"
                    |   "Whole" = Yes
                    |   "Leaf" = No
                    |   "BSD Name" = "disk2"
                    |   "Ejectable" = Yes
                    |   "Preferred Block Size" = 512
                    |   "IOMediaIcon" = {"IOBundleResourceFile"="Removable.icns","CFBundleIdentifier"="com.apple.iokit.IOStorageFamily"}
                    |   "BSD Minor" = 8
                    |   "IOGeneralInterest" = "IOCommand is not serializable"
                    |   "Writable" = Yes
                    |   "BSD Major" = 1
                    |   "Size" = 16147022336
                    |   "IOBusyInterest" = "IOCommand is not serializable"
                    |   "Open" = Yes
                    |   "Content Hint" = ""
                    |   "BSD Unit" = 2
                    | }
                    | 
                    +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x100002665, registered, matched, active, busy 0$
                    |   {
                    |     "IOClass" = "IOMediaBSDClient"
                    |     "IOMatchCategory" = "IOMediaBSDClient"
                    |     "IOProbeScore" = 30000
                    |     "IOProviderClass" = "IOMedia"
                    |     "IOResourceMatch" = "IOBSD"
                    |     "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                    |   }
                    |   
                    +-o IOFDiskPartitionScheme  <class IORegistryEntry:IOService:IOStorage:IOPartitionScheme:IOFDiskPartitionScheme, id 0x100002$
                      | {
                      |   "IOPropertyMatch" = {"Whole"=Yes}
                      |   "IOProbeScore" = 3000
                      |   "IOMatchCategory" = "IOStorage"
                      |   "IOClass" = "IOFDiskPartitionScheme"
                      |   "IOProviderClass" = "IOMedia"
                      |   "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                      |   "Content Mask" = "FDisk_partition_scheme"
                      |   "Content Table" = {"0xA9"="NetBSD","0x82"="Linux_Swap","0x01"="DOS_FAT_12","0xA7"="Apple_Rhapsody_UFS","0x0B"="DOS_FAT$
                      | }
                      | 
                      +-o Untitled 1@1  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x10000266b, registered, matched, active, busy 0 $
                        | {
                        |   "Removable" = Yes
                        |   "Content" = "DOS_FAT_32"
                        |   "Whole" = No
                        |   "Leaf" = Yes
                        |   "BSD Name" = "disk2s1"
                        |   "Ejectable" = Yes
                        |   "Preferred Block Size" = 512
                        |   "Base" = 4194304
                        |   "BSD Minor" = 9
                        |   "IOGeneralInterest" = "IOCommand is not serializable"
                        |   "Writable" = Yes
                        |   "Partition ID" = 1
                        |   "BSD Major" = 1
                        |   "Size" = 16142827520
                        |   "IOBusyInterest" = "IOCommand is not serializable"
                        |   "Open" = Yes
                        |   "Content Hint" = "DOS_FAT_32"
                        |   "BSD Unit" = 2
                        | }
                        | 
                        +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x10000266c, registered, matched, active, bu$
                            {
                              "IOClass" = "IOMediaBSDClient"
                              "IOMatchCategory" = "IOMediaBSDClient"
                              "IOProbeScore" = 30000
                              "IOProviderClass" = "IOMedia"
                              "IOResourceMatch" = "IOBSD"
                              "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                            }

首先,返回的错误代码是什么?我猜是 kIOReturnExclusiveAccess,但最好能确定一下。

其次,设备是否报告为复合设备?在这种情况下,您不应尝试打开 USB device,而应尝试打开您感兴趣的 USB interface

如果仍然失败,或者它不是复合设备,则此问题通常意味着另一个驱动程序已经声明了该设备。使用 IORegistryExplorer.app 或 ioreg 命令行工具检查以找出打开设备的进程或内核驱动程序。

我想我有我的问题的原因。我发现确实,为了命令相机我需要发送批量命令,因为相机控制是通过批量控制隧道传输的。您发出带有相机将响应的嵌入式自定义命令的批量命令。

我在用 PK_Tether 与摄像头对话时看到了在 PC 上使用 Wireshark 的批量命令。 (另一个有趣的事实是 pk_tether 无法访问大容量存储,除非我在相机卡槽中插入了 SD 卡。)

所以现在我必须弄清楚如何发出批量命令,所以我会在新线程中提出这个问题。