Jump to content

GenericUSBXHCI USB 3.0 driver for OS X with source


929 posts in this topic

Recommended Posts

I'm using a macbook 8,3 2011 (sandy bridge, 17" with expresscard) and 10.8.3. Expresscards with asmedia 1042, nec 720202 and fresco logic 1000, and 1009 all work, mount usb 2 and usb 3 drives but none of them resume after sleep. I get the disconnected drive error message and then the drives remount. I suspect its something to do with how the macbook initialises theexpresscards - modified PXHCD and oyen's MXHCD kexts do resume after sleep, I find pxhcd prone to disconnects, and while they both mount drives under 'superspeed' in system information, they list the max speed as 480mbps instead of 5gbps like your driver or apple's kext when patched. I don't know if sleep will ever work for me anyway, but thanks for all your work, I do run hackintoshes too.

modified PXHCD and oyen's MXHCD kexts do resume after sleep
Well, if they do it means it can be done... I'll try to figure out what PXHCD is doing to accomplish that. I assume by "modified" you're referring to modbin's patch?

 

Edit: Hmm... PXHCD uses some code from AppleUSBEHCI for ExpressCardPort... stay tuned.

Edit: It's doing something specific to an express card, but that's not the reason it's able to resume. What PXHCD does on wake it to reset the controller, and internally reenumerate all devices. Functionally, it's the same result as having IOUSBFamily reenumerate all devices, except you don't see the ejection messages, because IOUSBFamily doesn't know about the 'silent' reenumeration. It also has a side-effect of readdressing all devices. Since device addresses may change, they have to be mapped so IOUSBFamily continues to see the old addresses.

PXHCD doesn't try xhci suspend/resume at all.

I've considered this option before as a recovery from a failed suspend/resume. It's a lot of work to implement, and all just to hide those ejection messages (since otherwise as I said - functionally the same result.) So it's not gonna happen in GenericUSBXHCI.

 

I find pxhcd prone to disconnects, and while they both mount drives under 'superspeed' in system information, they list the max speed as 480mbps instead of 5gbps like your driver or apple's kext when patched.
Just to clear that part up...
  • Software has no control on whether a USB3 device connects as a high-speed or super-speed. It's the chip that decides that based on the electronic detection circuits and once decided, whatever channel is chosen is the one used for chip<->device communication.
  • PXHCD and MXHCD present the device as a high-speed device to IOUSBFamily, because that's all it supported prior to OS 10.7.something.
  • The question of whether a device can reach its peak performance has to do with whether it's programmed with the highest allowed packetization parameters. Superspeed drives allow much bigger burst transfers than high-speed.
  • The packetization parameters are ostensibly read from the device itself via its descriptors, and passed down from IOUSBFamily.
  • Superspeed devices have slightly different format (and limits) for packetization parameters.
  • So it's unclear what happens to the packetization parameters when a superspeed device is presented as a highspeed device to IOUSBFamily. It may be that it ends up programmed with sub-optimal parameters. It may be that PXHCD or MXHCD somehow tweak the whole process so that the device ends up with the best parameters anyway.

Edited by Zenith432
  • Like 1

Thanks for the analysis. - I'm really only concerned with the error message if it means it's possible to lose date - i.e. if the caches don't get written before sleep.

 

PXHCD was the modbin patched version, but I removed the device id from the inf so it loaded for a variety of cards in the specified class. I modified the MXHCD inf the same way, but the binary didn't need patching as it's not locked to any specific device.

 

Speed wise I find them on a par with the patched apple kext and with your generic kext, in banchmarks mxhcd is the fastest by a not-noticeable margin, but also more reliable than pxhcd. If it's simply re-enumerating after sleep I might switch to apple/generic

 

Is there any way to hack mxhcd to present the device as superspeed to iousbfamily?

 

NDS USB 3.0 Driver if you want to compare it to pxhcd

I'm really only concerned with the error message if it means it's possible to lose date - i.e. if the caches don't get written before sleep.
I don't know, looks like this is a common problem. Do a search for "eject drives before sleep mac" and you'll find some scripts that automate external drive ejection b4 sleep.

 

I may implement the 'silent reenumeration' that PXHCD does later on. It's a lower-priority item than isoch endpoints though. I've thought about it, and if it's the same drive, then doing a silent reenumation may prevent data-corruption - since the upper layer driver doesn't know the disk disconnected, and doesn't throw away the caches.

Drawback is - it's never really safe to do anything but a fully-broadcast reenumeration if xhci chip loses power. Why? because when sleeping without power, chip stops detecting connection changes on the ports. For instance, I have two USB thumbsticks that are the same model. The only difference is the content of the data blocks. Say system is put to sleep with one drive connected, and xhci chip loses power. I unplug the disk and put in the other one. Then I wake the system. PXHCD does silent reenumeration. The upper-layer driver believes it's the same disk and uses previous caches... data corruption on 2nd disk.

 

When putting a xhci chip to aux-powered sleep with xhci suspend, it continues to detect connection changes on the ports. When you unplug a device, it wakes up the system into darkwake (screen remains off), and the connection change is handled just like a fully-wake connection change. So you know for sure whether a device was replaced or not during sleep. With ports powered off - you can't know that... PXHCD just assumes it's the same device...

 

Is there any way to hack mxhcd to present the device as superspeed to iousbfamily?
Not by bin-patching, it's a ton of code that needs to be added. But if you get peak-performance with it, it makes no difference. It's just one driver cheating another driver to get things working right.

 

I'll check the Oyen kext when I have time.

 

Edit: mXHCD is the strangest of them... It does xhci suspend-resume, but at the end of the resume, without checking if the resume failed, it proceeds to reset the chip (!). I didn't follow it much after that, but looks like it's reinitializing everything. If you're not getting disk ejection notices after a reset, it must be doing an internal reenumeration like PXHCD. Are you sure the drives work after sleep?

Thanks - a couple of things I noticed about mxhcd when I did an ioreg -xrc - it shows all cards as 'built in' when other drivers do not. If you can find out how it's doing that it might be useful. Also generic or apple or both (can't remember) list the superspeed port as simulated, and mxhcd doesn't. Don't know whether that means anything.

 

Considering the amount of work involved in the pxhcd method I would pick data integrity (or at least being told that the disks got ejected,) over silent reenumeration. Not knowing what's happening is worse.

 

The drives definitely work after sleep with mxhcd. If it performs xhci suspend-resume presumably that means it flushes the caches before sleeping? Could you block it from resetting the chip after it's suspend-resume? - I'd be interested to see if that works and for which chipsets it works. Then we'd have an example of a driver that makes things built-in and does xhci suspend-resume successfully.

I uploaded release 1.1.

It contains some fixes for problem mentioned in #24 - KPed sometimes during suspend/resume code due to interrupt timing.

If this is stable for a while, I'll delete the older builds 1.1a3, 1.1a4.

 

Thanks - a couple of things I noticed about mxhcd when I did an ioreg -xrc - it shows all cards as 'built in' when other drivers do not.
That's no big mystery. They all (GenericUSBXHCI too) enable PME and mark the card as "built-in". It's just AppleUSBXHCI that's got issues with this, because it checks some Apple device-properties before doing so. There's no need for that. It's always right to enable PME on PCI endpoints that support it (well, not quite, some chips report they support it and then assert PME when they shouldn't). That should also be enough to get aux power during sleep - but unfortunately, it's not. [Correction: GenericUSBXHCI only marks it "built-in" if it supports PME. I think PXHCD always marks it as built-in].

 

Also generic or apple or both (can't remember) list the superspeed port as simulated, and mxhcd doesn't. Don't know whether that means anything.
It doesn't. There are 2 root hubs - superspeed and highspeed, and they're call "simulated" because they're not external USB hubs which are "real" hubs. It's just a name the kext itself chooses.

 

Considering the amount of work involved in the pxhcd method I would pick data integrity over silent reenumeration, or at least being told that the disks got ejected. Not knowing what's happening is worse.
I think PXHCD's method does add integrity as long as you don't swap the drive during sleep. It reenumerates the drive silently - the disk-cache handler doesn't know about the power loss - and continues to use the cache as if nothing happened.

 

If it performs xhci suspend-resume presumably that means it flushes the caches before sleeping?
No, no it's got nothing to do with flushing the caches. The caches are managed by a completely different part of the system (higher-layered drivers), and it's up to them to decide if to flush the caches.

 

Could you block it from resetting the chip after it's suspend-resume?
Why? That's the only reason it succeeds in continuing to function after resume. Your expresscards lose power, and AppleUSBXHCI gets hosed precisely because it doesn't reset the chip.

suspend/resume only works if the cards don't lose power.

All makes sense..

 

Why - to see if it does lose power during sleep with all drivers. The 720202 at least should resume after sleep and does on pcs with generic/apple-patched, and doesn't on my macbook. Is that the expresscard, or the way the mac talks to expresscards, or the drivers?

 

Sleepy.

…and as I'm typing this, I discover "xhcdump options" and find that the "-gux_nosleep" kernel flag lets me sleep and still enjoy USB 2.0 goodness with my USB 3.0 ports. A workaround, I know, but still a brilliant improvement over the CalDigit drivers, nevertheless.

 

---

 

Thank you very much for the ASM1042 support. I was previously using CalDigit's drivers, which worked fine with USB 3.0 devices but wouldn't handle USB 2.0 devices being plugged into the USB 3.0 ports correctly. This is on an ASUS N55SL laptop running 10.8.3 with XHCI handoff enabled in the BIOS and firmware 12220E running on the ASM1042. While I doubt it has any relevance, on this laptop, ASUS have something they call "USB Charger", which lets the laptop supply power to one of its USB 3.0 ports when the laptop is off.

 

However, I'm having trouble putting my laptop to sleep. With no devices connected, my laptop will sleep and then wake up right away. With the CalDigit drivers, this was solved with a DSDT edit posted here: http://www.osx86.net/view/2958-asmedia_usb_3.0_chip1042_fully_working_...html

The same DSDT edit has no effect with GenericUSBXHCI.kext version 1.1. With the DSDT lines removed the same behaviour occurs.

 

Here is a part of a log from around the time I tried to sleep (at the login screen, with no devices attached). Even with "gux_log=2" set, I don't get any differing output.

 

hibernate image path: /var/vm/sleepimage
hibernate_alloc_pages act 68005, inact 5446, anon 342, throt 0, spec 126162, wire 265599, wireinit 73045
hibernate_setup(0) took 0 ms
sizeof(IOHibernateImageHeader) == 512
kern_open_file_for_direct_io(0) took 264 ms
Opened file /var/vm/sleepimage, size 8589934592, partition base 0x0, maxio 400000 ssd 0
hibernate image major 1, minor 0, blocksize 512, pollers 5
(Re-)enabled Turbo Boost: 4000850089 -> 850089
SaveControllerStateForSleep: xHC Save Error
        0 [Time 1363832035] [Message hibernate_page_list_setall(preflight 0) start 0xffffff80d12b8000, 0xffffff80d12f8000
hibernate_page_list_setall time: 302 ms
pages 435895, wire 236247, act 42947, inact 1, cleaned 0 spec 17, zf 297, throt 0, could discard act 22875 inact 5205 purgeable 1496 spec 126810 cleaned 0
hibernate_page_list_setall found pageCount 279509
IOHibernatePollerOpen, ml_get_interrupts_enabled 0
IOHibernatePollerOpen(0)
encryptStart 13290
bitmap_size 0x3f4c0, previewSize 0x57fbe8, writing 277953 pages @ 0x5d2338
encryptEnd 73a8a00
image1Size 0xb4a5c00, encryptStart1 0x13290, End1 0x73a8a00
encryptStart b4a5c00
encryptEnd ee0fe00
PMStats: Hibernate write took 4052 ms
all time: 4052 ms, comp bytes: 1138495488 time: 608 ms 1783 Mb/s, crypt bytes: 181401968 time: 333 ms 519 Mb/s, 
image 249626112 (2%), uncompressed 1138495488 (277953), compressed 241989824 (21%), sum1 441f7f05, sum2 fde1a6ea
wired_pages_encrypted 172324, wired_pages_clear 62367, dirty_pages_encrypted 43262
hibernate_write_image done(0)
sleep
Disabled Turbo Boost: 850089 -> 4000850089
Wake reason = XHCI
No interval found for . Using 8000000
RTC: PowerByCalendarDate setting ignored
Previous Sleep Cause: 5
RestoreControllerStateFromSleep: xHC Restore Error

 

Here are some xhcdump results obtained when the laptop had no devices connected to any of its USB ports:

Minitrue:GenericUSBXHCI_1.1 $./xhcdump caps
Found a device of class GenericUSBXHCI: IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP04@1C,3/IOPCI2PCIBridge/XHCI@0/GenericUSBXHCI
Vendor 0x1b21, Device 0x1042, Revision 0
CapLength  32
HCIVersion 0x96
MaxSlots 32, MaxIntrs 8, Rsvd(1) 0, MaxPorts 4
IST 1 microframes, ERST Max 32768, Rsvd(2) 0x17, SPR N, Max Scratchpad Bufs 0
U1 Device Exit Latency 0, Rsvd(3) 0, U2 Device Exit Latency 0
AC64 N, BNC N, CSZ N, PPC N, PIND N, LHRC N, LTC N, NSS Y, Rsvd(4) 0x1, MaxPSASize 65536
 xHC Extended Cap ID 1, Specific 0
   Legacy CTLSTS 0x10000
 xHC Extended Cap ID 2, Specific 0x300
   Supported Protocol Name 0x20425355 PortOffset 1 PortCount 2 ProtocolDefined 0
 xHC Extended Cap ID 2, Specific 0x200
   Supported Protocol Name 0x20425355 PortOffset 3 PortCount 2 ProtocolDefined 0x1
DBOff  0x1800
RTSOff 0x1000
PageSize 4096
Using MSI

Minitrue:GenericUSBXHCI_1.1 $./xhcdump running
Found a device of class GenericUSBXHCI: IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP04@1C,3/IOPCI2PCIBridge/XHCI@0/GenericUSBXHCI
USBCmd RS Y HCRST N INTE Y HSEE N LHCRST N CSS N CRS N EWE Y EU3S N
USBSts HCH N HSE N EINT Y PCD N SSS N RSS N SRE N CNR N HCE N
DNCtrl 0xffff
CRCr CRR Y
Config 32
MFIndex 234
Last Time Sync xHC 272384 milliseconds <-> CPU 328512475030 nanoseconds
# Configured Endpoints 0
# Interrupts: Total 137, Serviced 137, Inactive 0, Offline 0
# Save Errors 1
# Restore Errors 1
Port   1 PortSC CCS N PED N OCA N PR N
          PLS RxDetect PP Y Speed Unknown PIC Off LWS N
          CSC N PEC N WRC N OCC N PRC N PLC N CEC N CAS N
          WCE Y WDE Y WOE Y DR N WPR N
        PortPmsc U1 0 U2 0 FLA N PortLi LEC 0
Port   2 PortSC CCS N PED N OCA N PR N
          PLS RxDetect PP Y Speed Unknown PIC Off LWS N
          CSC N PEC N WRC N OCC N PRC N PLC N CEC N CAS N
          WCE Y WDE Y WOE Y DR N WPR N
        PortPmsc U1 0 U2 0 FLA N PortLi LEC 0
Port   3 PortSC CCS N PED N OCA N PR N
          PLS RxDetect PP Y Speed Unknown PIC Off LWS N
          CSC N PEC N WRC N OCC N PRC N PLC N CEC N CAS N
          WCE Y WDE Y WOE Y DR N WPR N
        PortPmsc L1S Invalid RWE N HIRD 50 us L1Slot 0 HLE N TestMode Disabled
Port   4 PortSC CCS N PED N OCA N PR N
          PLS RxDetect PP Y Speed Unknown PIC Off LWS N
          CSC N PEC N WRC N OCC N PRC N PLC N CEC N CAS N
          WCE Y WDE Y WOE Y DR N WPR N
        PortPmsc L1S Invalid RWE N HIRD 50 us L1Slot 0 HLE N TestMode Disabled
Interrupter 0 iman IP N imod I 40000 ns C 0 ns erstsz 1 erdp DESI 0 EHB N

Minitrue:GenericUSBXHCI_1.1 $./xhcdump bandwidth
Found a device of class GenericUSBXHCI: IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP04@1C,3/IOPCI2PCIBridge/XHCI@0/GenericUSBXHCI
Bandwidth for RootHub, Speed 0
 0  0  90  90
Bandwidth for RootHub, Speed 1
 0  0  90  90
Bandwidth for RootHub, Speed 2
 0  0  80  80
Bandwidth for RootHub, Speed 3
 90  90  0  0

  • Like 1

This kext works perfectly, except that when I log out and back in I get a full system freeze, as well as intermittently on startup. Caldigit drivers do the same thing. I'm using the Etron EJ168 built in to my motherboard.

qwerty12: The save errors in the log indicate ASM1042 cannot sleep, and you should use '-gux_nosleep' in your Boot.plist permanently. That is not just a workaround, but the best way to handle a chip that can't sleep. Let me know if it wakes-up instantly when you boot with "-gux_nosleep", because that would need a fix.

Edit: I sent you a build with an attempt to fix the instant wakeup without a kernel flag. Let me know how it works out.

 

jamiethemorris: Why do you think those freezes have anything to do with the xhci drivers? Have tried it without any xhci drivers?

Thankyou very much! My s3-391 (Ivy bridge version) now has functioning USB 3.0 ports!

 

Tested with usb2 and usb3 devices and they seem to work. It seems to crash when i unplugged a device once, but hasnt done it again yet.

 

 

If i try and sleep now i just get a black screen though and cant wake up.

 

Also, if i bootup with my sdcard reader plugged . Once it gets to the desktop, a message appears saying 'Disk unreadable'

If i unplug, re-plug its ok. Could be a power issue? I notice the reader felt very hot which is not normal.

 

Will keep testing!

 

EDIT: it appears if i add the boot flag ' -gux_defer_usb2 ' it solves all my problems!

 

What is the correct way to add this to chameleon boot?

If i try and sleep now i just get a black screen though and cant wake up.

 

Also, if i bootup with my sdcard reader plugged . Once it gets to the desktop, a message appears saying 'Disk unreadable'

If i unplug, re-plug its ok. Could be a power issue? I notice the reader felt very hot which is not normal.

 

EDIT: it appears if i add the boot flag ' -gux_defer_usb2 ' it solves all my problems!

 

What is the correct way to add this to chameleon boot?

For Intel Series 7, when the xhci driver initializes, it yanks control of the USB 2.0 ports away from the ehci driver (assuming the ehci driver initialized earlier). This may cause problems for some devices. I'm not sure what to do about this. For the time being, if this gives you trouble, go ahead and leave the ports with the ehci driver by "-gux_defer_usb2".

You can add permanent kernel flags in /Extra/org.chameleon.Boot.plist in the "Kernel Flags" entry.

Edit: Try looking in your bios settings if it's possible to route the ports to xhci from boot-time, that may also solve the problem (instead of "-gux_defer_usb2").

 

I uploaded v1.1.4 (see post #1). Anyone that's being having trouble with not-coming-back-from-sleep, or spontaneous-reboot-on-shutdown, I suggest you try it, as I made code for those things more robust.

Edited by Zenith432

For Intel Series 7, when the xhci driver initializes, it yanks control of the USB 2.0 ports away from the ehci driver (assuming the ehci driver initialized earlier). This may cause problems for some devices. I'm not sure what to do about this. For the time being, if this gives you trouble, go ahead and leave the ports with the ehci driver by "-gux_defer_usb2".

You can add permanent kernel flags in /Extra/org.chameleon.Boot.plist in the "Kernel Flags" entry.

Edit: Try looking in your bios settings if it's possible to route the ports to xhci from boot-time, that may also solve the problem (instead of "-gux_defer_usb2").

 

I uploaded v1.1.3 (see post #1). Anyone that's being having trouble with not-coming-back-from-sleep, or spontaneous-reboot-on-shutdown, I suggest you try it, as I made code for those things more robust.

 

Thank you for the reply. The only option I can see in the bios similar to that is 'load xhci at preboot' which is already enabled.

 

With -gux_defer_usb2 , my webcam works again and is listed under usb2 in system profile. Similarly, if I plug in a usb3 device it will correctly be listed under usb3 . I haven't performed a speed test yet but to me it suggests its working?

 

Sleep works, usb storage doesn't give any error after wake up and everything seems to plug in and work now!

  • Like 1

I've been working on an open source USB 3.0 driver for OS X for a while, and decided it's stable enough to be published.

 

...

 

Binaries contain

  • build for OS 10.8.
  • build for OS 10.7.
  • xhcdump utility..

 

Zenith432,

 

First of all nice work on this driver...

 

I've been looking at building a single binary for 10.7 and 10.8 and I thought I'd ask you some questions.

 

I noticed the #ifdefs checking for 10.7 build target... one example:

 

#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1072
if (getProperty("IOPCITunnelled", gIOServicePlane) == kOSBooleanTrue) {
_v3ExpansionData->_onThunderbolt = true;
requireMaxBusStall(25000U);
}
#endif

 

Looks like the code is protecting against writing to parts of _v3ExpansionData that don't exist on earlier versions of Lion (10.7.1 and prior). My intention was to do these checks at runtime instead and this prompted me to review all access to _v3ExpansionData and to do some research on how it has changed over OS X versions.

 

Compiled by looking at each version of IOUSBControllerV3.h at opensource.apple.com:

 

// 10.8.2 IOUSBControllerV3::V3ExpansionData
struct V3ExpansionData {
uint32_t _rootHubPollingRate32;
bool _rootHubTransactionWasAborted;
IOPMDriverAssertionID _externalUSBDeviceAssertionID;
SInt32 _externalDeviceCount;
UInt32 _inCheckPowerModeSleeping;
bool _onThunderbolt;
// added 10.7.2
uint32_t _thunderboltModelID;
uint32_t _thunderboltVendorID;
// added 10.7.5 (#ifdef SUPPORTS_SS_USB)
UInt8 _rootHubNumPortsSS;
UInt8 _rootHubNumPortsHS;
UInt8 _rootHubPortsHSStartRange;
UInt8 _rootHubPortsSSStartRange;
IOUSBRootHubInterruptTransaction _outstandingSSRHTrans[4];
// added 10.8.2
bool _wakingFromStandby; // t when waking from S4 stanby
};

 

The code in GenericUSBXHCI uses the following fields:

_onThunderbolt

_rootHubNumPortsSS

_rootHubPortsSSStartRange

_rootHubNumPortsHS

_rootHubPortsHSStartRange

_externalDeviceCount

 

The _rootHub* fields are used without protection, even though they are only present in 10.7.5+.

The _onThunderbolt is accessed with protection in a couple of places (like the #if noted above), but others it is accessed without protection, even though only present on 10.7.2+.

The _externalDeviceCount is there in all versions (even 10.6.8).

 

What is the intention here? Thanks in advance...

 

P.S. This is my first look into Apple's kext backward/forward compatibility and frankly I'm a bit shocked at the fragility of the whole thing.

thank you! :wink2: :wink2: :wink2:

 

USB 3.0 SuperSpeed Bus:

 

Host Controller Location: Built-in USB

Host Controller Driver: GenericUSBXHCI

PCI Device ID: 0x1042

PCI Revision ID: 0x0000

PCI Vendor ID: 0x1b21

Bus Number: 0xbc

 

USB to ATA/ATAPI Bridge:

 

Product ID: 0x0539

Vendor ID: 0x152d (JMicron Technology Corp.)

Version: 0.0f

Serial Number: WD-WMAZA7774525

Speed: Up to 5 Gb/sec

Manufacturer: JMicron

Location ID: 0xbc900000 / 1

Current Available (mA): 900

Current Required (mA): 2

Capacity: 2 TB (2,000,398,841,856 bytes)

Removable Media: Yes

Detachable Drive: Yes

BSD Name: disk6

Partition Map Type: MBR (Master Boot Record)

S.M.A.R.T. status: Not Supported

Volumes:

UNTITLED:

Capacity: 2 TB (2,000,396,746,752 bytes)

Available: 1.78 TB (1,775,855,992,832 bytes)

Writable: Yes

File System: ExFAT

BSD Name: disk6s1

Mount Point: /Volumes/UNTITLED

Content: Windows_NTFS

Volume UUID: E2745740-BE7E-3ABE-83DA-207986834C3A

since 1.1.3 sleep not working anymore, i went back to 1.1 and sleep works. ux32vd on ml 10.8.2. it goes to sleep, but wake up with a reboot, with 1.1 no problem at all

 

GenericUSBXHCI.kext;1.1.0;7 Series/C210 Series Chipset Family USB xHCI Host Controller;0c03

  • Like 2
The _rootHub* fields are used without protection, even though they are only present in 10.7.5+.

The _onThunderbolt is accessed with protection in a couple of places (like the #if noted above), but others it is accessed without protection, even though only present on 10.7.2+.

The _externalDeviceCount is there in all versions (even 10.6.8).

What is the intention here? Thanks in advance...

There's no grand design there, just historical order of development. When I first ran into the thunderbolt code, I'd never done anything with thunderbolt before, so I went back and checked exactly which version it began.

For the _rootHub* fields, I looked in 10.7.5 and saw it's #ifdefed. I didn't know whether the distributed kexts were built with the symbols defined or not, so I stopped there and didn't look earlier.

In retrospect, 10.7.5 kexts were built with the symbols defined, so GenericUSBXHCI can be used with it.

OS 10.7.4 and earlier had no support for superspeed devices. So you won't be able to simply make them work. They can only be supported by simulation like PXHCD/mXHCD/Caldigit do, and it's a complicated simulation to develop. I explained in an earlier post why (slightly different descriptors from USB 2.0 to USB 3.0)

If you make enough of the code conditional, you can probably get it to manage USB 2.0 devices on xhci with OS 10.7.4 and earlier.

Note that in OS 10.6.8 some of the fields in IOUSBController, IOUSBControllerV2 were different, so it gets even more complicated...

If you want to check stuff into the repository, let me know.

Edited by Zenith432

There's no grand design there, just historical order of development. When I first ran into the thunderbolt code, I'd never done anything with thunderbolt before, so I went back and checked exactly which version it began.

For the _rootHub* fields, I looked in 10.7.5 and saw it's #ifdefed. I didn't know whether the distributed kexts were built with the symbols defined or not, so I stopped there and didn't look earlier.

In retrospect, 10.7.5 kexts were built with the symbols defined, so GenericUSBXHCI can be used with it.

OS 10.7.4 and earlier had no support for superspeed devices. So you won't be able to simply make them work. They can only be supported by simulation like PXHCD/mXHCD/Caldigit do, and it's a complicated simulation to develop. I explained in an earlier post why (slightly different descriptors from USB 2.0 to USB 3.0)

If you make enough of the code conditional, you can probably get it to manage USB 2.0 devices on xhci with OS 10.7.4 and earlier.

Note that in OS 10.6.8 some of the fields in IOUSBController, IOUSBControllerV2 were different, so it gets even more complicated...

If you want to check stuff into the repository, let me know.

 

My intention is not to make it work on 10.7.4 or prior, but I do want it to gracefully exit if installed...

 

What I've done with my repo is:

- removed the #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1072 checks from V1Overrides.cpp and V1Pure.cpp

(because we are always on 10.7.5 or greater)

- set the OS X target to 10.7 (SDK is still 10.8)

- added this to GenericUSBXHCI.h:


#define MakeKernelVersion(maj,min,rev) (maj<<16|min<<8|rev)
#include <libkern/version.h>
#define GetKernelVersion() MakeKernelVersion(version_major,version_minor,version_revision)

- added a check in ::init to be sure driver doesn't start if prior to 10.7.5

// after call to super::init


   // do not load if prior to OS X 10.7.5
   if (GetKernelVersion() < MakeKernelVersion(11,4,2)) {
       IOLog("%s: Only 10.7.5 or greater is supported.\n", __FUNCTION__);
       return false;
   }

 

I've also optimized the build settings a bit to reduce the kext to 116 KB (binary is 114 KB). BTW, it looks like your Lion build might have debug symbols in it or something (256 KB). Mostly hiding symbols, turning LinkTime Optimize on, dead code elimination on, etc. With these options the only symbol exported is _kmod_info. You could get rid of all the __attribute__((visibility("hidden"))) using my build settings (I didn't bother as I didn't want to introduce huge diffs).

 

My fork is at: https://github.com/RehabMan/OS-X-Generic-USB3

 

Let me know if something I've done doesn't make sense... Thanks!

  • Like 2
My intention is not to make it work on 10.7.4 or prior, but I do want it to gracefully exit if installed...
Info.plist asks for IOUSBFamily version 5.0.0a1 or later. So in fact it will gracefully not load at all on 10.7.4 or prior :)

A build compiled for min-version 10.7.5 with dual-arch should work on 10.8+, and a build compiled for min-version 10.8 (dual-arch) can functionally work on 10.7.5, but I'm not sure will load - ld may stick some load commands not supported in 10.7.5. This needs to be checked if important.

  • Like 1

Info.plist asks for IOUSBFamily version 5.0.0a1 or later. So in fact it will gracefully not load at all on 10.7.4 or prior :)

 

Good to know. I didn't even think to check that (I think because I saw the #ifs for 10.7.2...) I don't even have a 10.7.4 install to test, I was just wanting to be sure... Oh well, the code I added will handle the case that misguided soul decides to edit the Info.plist.

 

A build compiled for min-version 10.7.5 with dual-arch should work on 10.8+, and a build compiled for min-version 10.8 (dual-arch) can functionally work on 10.7.5, but I'm not sure will load - ld may stick some load commands not supported in 10.7.5. This needs to be checked if important.

 

Heh heh... I just realized that your kext does support 32-bit, which I don't really plan to use. Makes sense that your 10.7 build was dual-arch; mine won't be... I think I was getting confused between your usb3 and Meize's realtek driver, which won't build 32-bit... (working on both right now). I will update my README.md/project to reflect.

 

And yes, I don't know if there is any material difference between building w/ target set to 10.7 vs. 10.8. In theory, Apple should have their headers appropriately #ifdef, such that if say target '10.7' you can't accidentally use something that is not in 10.7. In practice, we know they are not that diligent with their SDK (I think they don't bother at all). kexts don't have the "Minimum system version' that apps do. Instead they have, as you say, the OSBundleLibraries dictionary. Whether ld sets something in the actual binary to indicate OS X target, I don't really know (but I think not).

 

Thanks!

Zenith,

 

BTW, 10.7.5 is Darwin 11.4.2 (not 11.5)

 

see: http://en.wikipedia....Release_history

and for ML: http://en.wikipedia....Release_history

 

I think you will soon see why I used the MakeKernelVersion/GetKernelVersion macros... Yes, I saw your latest commit :-)

  • Like 1
  • Allan unpinned this topic
×
×
  • Create New...