bool com_yaqinking_MyFirstUSBDriver::start(IOService *provider)
{
    IOUSBInterface* interface;
    IOUSBFindEndpointRequest request;
    IOUSBPipe* pipe = NULL;
    
    IOLog("%s(%p)::start \n",getName(),this);
    
    if (!super::start(provider)) {
        return false;
    }
    
    interface = OSDynamicCast(IOUSBInterface, provider);
    if (interface == NULL) {
        IOLog("%s(%p)::start -> provider not a IOUSBInterface \n",getName(),this);
        return false;
    }
    
    request.type = kUSBBulk;
    request.direction = kUSBOut;
    pipe = interface->FindNextPipe(NULL, &request,true);
    if (pipe) {
        logEndPoint(pipe);
        pipe->release();
    }
    return true;
}
Exemplo n.º 2
0
bool XboxOneControllerDriver::handleStart(IOService *provider)
{
	IOUSBInterface* interface = nullptr;
	IOUSBPipe* interruptPipe = nullptr;
	IOReturn ior = kIOReturnSuccess;
	
	IOUSBFindEndpointRequest pipeRequest = {
		.type = kUSBInterrupt,
		.direction = kUSBOut,
	};
	
	// Apple says you should call super::handleStart at the *beginning* of the method.
	if (!super::handleStart(provider))
	{
		goto cleanup;
	}
	
	// Paranoid check: is it the correct kind of object?
	interface = OSDynamicCast(IOUSBInterface, provider);
	if (interface == nullptr)
	{
		IO_LOG_DEBUG("IOUSBHIDDriver is handling start on an object that's not a IOUSBInterface??");
		goto cleanup;
	}
	
	// Find the pipe through which we have to send the hello message.
	// This is redundant with work that IOUSBHIDDriver already did, but there are no accessors.
	interruptPipe = interface->FindNextPipe(nullptr, &pipeRequest);
	if (interruptPipe == nullptr)
	{
		IO_LOG_DEBUG("No interrupt pipe found on controller");
		goto cleanup;
	}
	
	// `sendHello` needs _interruptPipe to be set, but only retain it if it succeeds.
	_interruptPipe = interruptPipe;
	ior = sendHello();
	if (ior != kIOReturnSuccess)
	{
		IO_LOG_DEBUG("Couldn't send hello message: %08x", ior);
		_interruptPipe = nullptr;
		goto cleanup;
	}
	
	_interruptPipe->retain();
	
cleanup:
	return _interruptPipe != nullptr;
}
// Start device
bool WirelessGamingReceiver::start(IOService *provider)
{
    const IOUSBConfigurationDescriptor *cd;
    IOUSBFindInterfaceRequest interfaceRequest;
    IOUSBFindEndpointRequest pipeRequest;
    IOUSBInterface *interface;
    int iConnection, iOther, i;
    
    if (!IOService::start(provider))
    {
//        IOLog("start - superclass failed\n");
        return false;
    }

    device = OSDynamicCast(IOUSBDevice, provider);
    if (device == NULL)
    {
//        IOLog("start - invalid provider\n");
        goto fail;
    }

    // Check for configurations
    if (device->GetNumConfigurations() < 1)
    {
        device = NULL;
//        IOLog("start - device has no configurations!\n");
        goto fail;
    }
    
    // Set configuration
    cd = device->GetFullConfigurationDescriptor(0);
    if (cd == NULL)
    {
        device = NULL;
//        IOLog("start - couldn't get configuration descriptor\n");
        goto fail;
    }
    
    if (!device->open(this))
    {
        device = NULL;
//        IOLog("start - failed to open device\n");
        goto fail;
    }
    if (device->SetConfiguration(this, cd->bConfigurationValue, true) != kIOReturnSuccess)
    {
//        IOLog("start - unable to set configuration\n");
        goto fail;
    }
        
    for (i = 0; i < WIRELESS_CONNECTIONS; i++)
    {
        connections[i].controller = NULL;
        connections[i].controllerIn = NULL;
        connections[i].controllerOut = NULL;
        connections[i].other = NULL;
        connections[i].otherIn = NULL;
        connections[i].otherOut = NULL;
        connections[i].inputArray = NULL;
        connections[i].service = NULL;
        connections[i].controllerStarted = false;
    }
    
    pipeRequest.interval = 0;
    pipeRequest.maxPacketSize = 0;
    pipeRequest.type = kUSBInterrupt;
    interfaceRequest.bInterfaceClass = kIOUSBFindInterfaceDontCare;
    interfaceRequest.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
    interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
    interfaceRequest.bAlternateSetting = 0;
    interface = NULL;
    iConnection = 0;
    iOther = 0;
    while ((interface = device->FindNextInterface(interface, &interfaceRequest)) != NULL)
    {
        switch(interface->GetInterfaceProtocol())
        {
            case 129:   // Controller
                if (!interface->open(this))
                {
//                    IOLog("start: Failed to open control interface\n");
                    goto fail;
                }
                connections[iConnection].controller = interface;
                pipeRequest.direction = kUSBIn;
                connections[iConnection].controllerIn = interface->FindNextPipe(NULL, &pipeRequest);
                if (connections[iConnection].controllerIn == NULL)
                {
//                    IOLog("start: Failed to open control input pipe\n");
                    goto fail;
                }
                else
                    connections[iConnection].controllerIn->retain();
                pipeRequest.direction = kUSBOut;
                connections[iConnection].controllerOut = interface->FindNextPipe(NULL, &pipeRequest);
                if (connections[iConnection].controllerOut == NULL)
                {
//                    IOLog("start: Failed to open control output pipe\n");
                    goto fail;
                }
                else
                    connections[iConnection].controllerOut->retain();
                iConnection++;
                break;
            case 130:   // It is a mystery
                if (!interface->open(this))
                {
//                    IOLog("start: Failed to open mystery interface\n");
                    goto fail;
                }
                connections[iOther].other = interface;
                pipeRequest.direction = kUSBIn;
                connections[iOther].otherIn = interface->FindNextPipe(NULL, &pipeRequest);
                if (connections[iOther].otherIn == NULL)
                {
//                    IOLog("start: Failed to open mystery input pipe\n");
                    goto fail;
                }
                else
                    connections[iOther].otherIn->retain();
                pipeRequest.direction = kUSBOut;
                connections[iOther].otherOut = interface->FindNextPipe(NULL, &pipeRequest);
                if (connections[iOther].otherOut == NULL)
                {
//                    IOLog("start: Failed to open mystery output pipe\n");
                    goto fail;
                }
                else
                    connections[iOther].otherOut->retain();
                iOther++;
                break;
            default:
//                IOLog("start: Ignoring interface (protocol %d)\n", interface->GetInterfaceProtocol());
                break;
        }
    }
    
    if (iConnection != iOther)
        IOLog("start - interface mismatch?\n");
    connectionCount = iConnection;
    
    for (i = 0; i < connectionCount; i++)
    {
        connections[i].inputArray = OSArray::withCapacity(5);
        if (connections[i].inputArray == NULL)
        {
//            IOLog("start: Failed to allocate packet buffer %d\n", i);
            goto fail;
        }
        if (!QueueRead(i))
        {
//            IOLog("start: Failed to start read %d\n", i);
            goto fail;
        }
    }
    
//    IOLog("start: Transform and roll out (%d interfaces)\n", connectionCount);
    return true;
    
fail:
    ReleaseAll();
    return false;
}