RehabMan / OS-X-Voodoo-PS2-Controller

Contains updated Voodoo PS/2 Controller, improved Keyboard & Synaptics TouchPad

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Passthru detection occasionally failing.

jcsnider opened this issue · comments

I've been looking into errors that Thinkpad users have been recently experiencing with their nubs/trackpoints not working.

In @tluck's fork, he was on the right track in isolating the problem to passthru. He made a commit to force passthru and skippassthru to be true. (tluck@3b5d68a) What he didn't account for was skippassthru being set back to false in the setParamPropertiesGated function so his changes ultimately had no effect. I will reach out to him in order to patch the oversight.

The much larger concern at hand is that we need to be forcing passthru at all. I went on to compile this repo's kext in debug mode to explore. In the queryCapabilities function it looks like you're trying to determine if passthru is supported or not. There are two different components that are considered, whether or not it has the passthru capability (variable passthru2) and whether or not a guest is present (variable passthru1).

Looking at debug logs, every single time the queryCapabilities function is ran passthru2 is set to 1 as expected. But the passthru1 value is inconsistent, sometimes it's 1 and sometimes it's 0.

The code I'm questioning is pasted below:

        UInt8 passthru1 = 0;
        if (getTouchPadData(0x1, buf3))
        {
            // first byte, bit 0 indicates guest present
            passthru1 = buf3[0] & 0x01;
        }

I did confirm that each time the queryCapabilities function is ran the getTouchPadData function does return true. It seems like the buf3[0] value doesn't always end up being the same.

I'm pretty sure almost all Thinkpads are experiencing this problem. I'm not sure if other devices are or not. I'm happy to provide any information in order to help debug further.

Maybe timing related (too soon for trackpad firmware to respond positively on the "guest present"?
You might try adding a delay somewhere in the startup sequence (eg. directly in the queryCapabilities).

If there needs to be an override, we could easy add an Info.plist option, which could then be overridden with ACPI.

commented

i set both skippassthru and passthru true ... so I think it totally skips the above check or set of passthru1?

if (!skippassthru)
    {
        UInt8 passthru2 = buf3[2] >> 7;
        // see if guest device for pass through is present
        UInt8 passthru1 = 0;
        if (getTouchPadData(0x1, buf3))
        {
            // first byte, bit 0 indicates guest present
            passthru1 = buf3[0] & 0x01;
        }
        // trackpad must have both guest present and pass through capability
        passthru = passthru1 & passthru2;
#ifdef SIMULATE_PASSTHRU
        passthru = true;
#endif
        DEBUG_LOG("VoodooPS2Trackpad: passthru1=%d, passthru2=%d, passthru=%d\n", passthru1, passthru2, passthru);
    }

commented

@jcsnider - if i did miss something - let me know to force passthru. thanks

@tluck I was waiting for confirmation of my fix before opening an issue in your fork. I've gotten confirmation and sent the information your way :)

Rehabman: My ultimate goal, if possible, is to submit a PR that will get this repo to a Thinkpad/Trackpoint friendly state. I'll test with delays but I only have one Thinkpad to test with. A delay might have to be shorter/longer based on PC speed, so while it will be good for information purposes I don't like it as a long term solution.

The info.plist solution might end up being the best choice, we know that our devices support passthru so we could override. I will look through the code to see how that works as well.

@RehabMan:

Even with forcing passthrough, this block of code (FULL_HW_RESET) has to be ran in order for the trackpoint/nub to activate on Thinkpad machines. (This is used in tlucks fork as well)

Strangely enough, if I run this FULL_HW_RESET code BEFORE queryCapabilities then pass through is properly detected. (100% success thus far.)

As far as you know is this code harmful on any other devices? If not, and if I were to send a PR that does the reset prior to the queryCapabilities function would you accept that? This would make it so we don't need to add extra values to the info.plist files and it may solve problems with other make/model laptops that we don't even know about.

Thanks,
JC

    // This was an attempt to solve wake from sleep problems.  Not needed.
    int i = 0;
    request.commands[i].command = kPS2C_SendMouseCommandAndCompareAck;
    request.commands[i++].inOrOut = kDP_SetDefaultsAndDisable;     // F5
    request.commands[i].command = kPS2C_SendMouseCommandAndCompareAck;
    request.commands[i++].inOrOut = kDP_SetDefaultsAndDisable;     // F5
    request.commands[i].command = kPS2C_WriteCommandPort;
    request.commands[i++].inOrOut = kCP_TransmitToMouse;
    request.commands[i].command = kPS2C_WriteDataPort;
    request.commands[i++].inOrOut = kDP_Reset;                     // FF
    request.commands[i].command = kPS2C_ReadDataPortAndCompare;
    request.commands[i++].inOrOut = kSC_Acknowledge;
    request.commands[i].command = kPS2C_SleepMS;
    request.commands[i++].inOrOut32 = wakedelay*2;
    request.commands[i].command = kPS2C_ReadMouseDataPortAndCompare;
    request.commands[i++].inOrOut = 0xAA;
    request.commands[i].command = kPS2C_ReadMouseDataPortAndCompare;
    request.commands[i++].inOrOut = 0x00;
    request.commandsCount = i;
    DEBUG_LOG("VoodooPS2Trackpad: sending kDP_Reset $FF\n");
    assert(request.commandsCount <= countof(request.commands));
    _device->submitRequestAndBlock(&request);
    if (i != request.commandsCount)
        DEBUG_LOG("VoodooPS2Trackpad: sending $FF failed: %d\n", request.commandsCount);

Full reset would need to be conditional on something in the Info.plist that could then be overridden in ACPI. I don't think it should be default as it may cause issues with other laptops.

Also, did you test the delay idea?

No, once I found that forcing passthru wasn't enough, and that I have to do the hard reset anyways I didn't need the delay.

No matter what the delay it wouldn't be enough without the reset.

Edit: Created PR #150 in which these options are available.

This issue is resolved in pull #151.