Skip to content

Instantly share code, notes, and snippets.

@zhen-zen
Last active June 4, 2023 02:27
Show Gist options
  • Save zhen-zen/ce4d3108aaa6f8855e2f04fb0047c795 to your computer and use it in GitHub Desktop.
Save zhen-zen/ce4d3108aaa6f8855e2f04fb0047c795 to your computer and use it in GitHub Desktop.
//
// 8152Info.swift
// 8152Info
//
// Created by Zhen on 3/24/21.
//
import Foundation
import IOKit.usb
import IOKit.usb.IOUSBLib
// from https://github.com/Arti3DPlayer/USBDeviceSwift/blob/master/Sources/USBDevice.swift
// from IOUSBLib.h
public let kIOUSBDeviceUserClientTypeID = CFUUIDGetConstantUUIDWithBytes(nil,
0x9d, 0xc7, 0xb7, 0x80, 0x9e, 0xc0, 0x11, 0xD4,
0xa5, 0x4f, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61)
public let kIOUSBDeviceInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil,
0x5c, 0x81, 0x87, 0xd0, 0x9e, 0xf3, 0x11, 0xD4,
0x8b, 0x45, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61)
// from IOCFPlugin.h
public let kIOCFPlugInInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil,
0xC2, 0x44, 0xE8, 0x58, 0x10, 0x9C, 0x11, 0xD4,
0x91, 0xD4, 0x00, 0x50, 0xE4, 0xC6, 0x42, 0x6F)
let RTL8152_REQT_READ: UInt8 = 0xc0
let RTL8152_REQ_GET_REGS: UInt8 = 0x05
let PLA_TCR0: UInt16 = 0xe610
let MCU_TYPE_PLA: UInt16 = 0x0100
let VERSION_MASK: UInt32 = 0x7cf0
let idVendor: Int32 = 0x0bda
let idProduct: Int32 = 0x8156
let idProductArray: NSMutableArray = [0x8152, 0x8153, 0x8156]
var device: UnsafeMutablePointer<UnsafeMutablePointer<IOUSBDeviceInterface>?>?
var plugin: UnsafeMutablePointer<UnsafeMutablePointer<IOCFPlugInInterface>?>?
var score: Int32 = 0
var reg: UInt32 = 0
var kr: kern_return_t = 0
var iter: io_iterator_t = 0
// from https://github.com/LinusHenze/Fugu/blob/master/USB/IOKitUSB.swift
// IOIteratorNext, Swift Style
func IOIteratorNextOptional(_ iterator: io_iterator_t) -> io_service_t? {
let service = IOIteratorNext(iterator)
return service != 0 ? service : nil
}
var matchingDictionary: NSMutableDictionary = IOServiceMatching(kIOUSBDeviceClassName)
matchingDictionary[kUSBVendorID] = idVendor as NSNumber
//matchingDictionary[kUSBProductID] = idProduct as NSNumber
matchingDictionary[kUSBProductIdsArrayName] = idProductArray
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iter)
guard kr == kIOReturnSuccess else { exit(-1) }
print("Enumerating RTL8152 devices")
while let usbRef = IOIteratorNextOptional(iter) {
var deviceNameCString: [CChar] = [CChar](repeating: 0, count: 128)
kr = IORegistryEntryGetName(usbRef, &deviceNameCString)
if kr != kIOReturnSuccess {
print("Error getting device name")
}
print("Found:", String(cString: &deviceNameCString))
kr = IOCreatePlugInInterfaceForService(usbRef, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score)
guard kr == kIOReturnSuccess else {
print("Unable to create PlugIn Interface for Device", kr)
continue
}
IOObjectRelease(usbRef)
guard let pluginInterface = plugin?.pointee?.pointee else {
print("Unable to get Plugin Interface")
continue
}
kr = withUnsafeMutablePointer(to: &device) {
$0.withMemoryRebound(to: Optional<LPVOID>.self, capacity: 1) {
pluginInterface.QueryInterface(
plugin,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
$0)
}
}
guard kr == kIOReturnSuccess else {
print("Unable to query Device")
continue
}
_ = pluginInterface.Release(plugin)
guard let deviceInterface = device?.pointee?.pointee else {
print("Unable to get Device Interface")
continue
}
kr = deviceInterface.USBDeviceOpen(device)
guard kr == kIOReturnSuccess else {
if kr == kIOReturnExclusiveAccess{
print("Unable to gain Access")
} else {
print("Unable to open Device")
}
continue
}
var request = IOUSBDevRequest(
bmRequestType: RTL8152_REQT_READ,
bRequest: RTL8152_REQ_GET_REGS,
wValue: PLA_TCR0,
wIndex: MCU_TYPE_PLA,
wLength: 4,
pData: &reg,
wLenDone: 4
)
kr = deviceInterface.DeviceRequest(device, &request)
if kr != kIOReturnSuccess {
print("Unable to send Device request")
} else {
print(String(format:"PLA_TCR0: 0x%08X", reg))
let ver = reg >> 16 & VERSION_MASK
print(String(format:"Version: 0x%04X", ver))
switch ver {
case 0x4c00:
print("RTL_VER_01 - RT8152B")
case 0x4c10:
print("RTL_VER_02 - RT8152B")
case 0x5c00:
print("RTL_VER_03 - RT8153")
case 0x5c10:
print("RTL_VER_04 - RT8153")
case 0x5c20:
print("RTL_VER_05 - RT8153")
case 0x5c30:
print("RTL_VER_06 - RT8153")
case 0x4800:
print("RTL_VER_07 - RT8152B")
case 0x6000:
print("RTL_VER_08 - RT8153B")
case 0x6010:
print("RTL_VER_09 - RT8153B")
case 0x7010:
print("RTL_TEST_01 - RT8156")
case 0x7020:
print("RTL_VER_10 - RT8156")
case 0x7030:
print("RTL_VER_11 - RT8156")
case 0x7400:
print("RTL_VER_12 - RT8156B")
case 0x7410:
print("RTL_VER_13 - RT8156B")
case 0x6400:
print("RTL_VER_14 - RTL8153C")
default:
print("RTL_VER_UNKNOWN");
}
}
kr = deviceInterface.USBDeviceClose(device)
guard kr == kIOReturnSuccess else {
print("Unable to close Device")
continue
}
_ = deviceInterface.Release(device)
}
IOObjectRelease(iter)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment