// 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; }