IOReturn CLASS::UIMCreateInterruptTransfer(IOUSBCommand* command) { IOUSBCompletion comp; IOMemoryDescriptor* md; USBDeviceAddress addr; IODMACommand* dmac; uint32_t speed, tag; if (!command) return kIOReturnBadArgument; addr = command->GetAddress(); if (addr == _hub3Address || addr == _hub2Address) { comp = command->GetUSLCompletion(); dmac = command->GetDMACommand(); if (dmac && dmac->getMemoryDescriptor()) dmac->clearMemoryDescriptor(); if (command->GetEndpoint() == 1U) { md = command->GetBuffer(); if (!md) return kIOReturnInternalError; speed = (addr == _hub3Address ? kUSBDeviceSpeedSuper : kUSBDeviceSpeedHigh); tag = ((static_cast<uint32_t>(addr) << kUSBAddress_Shift) & kUSBAddress_Mask); tag |= ((speed << kUSBSpeed_Shift) & kUSBSpeed_Mask); md->setTag(tag); return RootHubQueueInterruptRead(md, static_cast<uint32_t>(command->GetReqCount()), comp); } else { Complete(comp, kIOUSBEndpointNotFound, static_cast<uint32_t>(command->GetReqCount())); return kIOUSBEndpointNotFound; } } return CreateTransfer(command, 0U); }
/*-----------------------------------------------------------------------------* * This routine queues an SRB to reset the SCSI Bus * *-----------------------------------------------------------------------------*/ void Sym8xxSCSIController::resetCommand( IOSCSIParallelCommand *scsiCommand ) { SRB * srb; IOMemoryDescriptor * iomd; // printf( "SCSI(Symbios8xx): resetCommand\n\r" ); srb = (SRB *) scsiCommand->getCommandData(); bzero( srb, sizeof(SRB) ); iomd = SCSI_IOMDs[ SCSI_RESET_IOMD ]; // special "target" for reset srb->srbIOMD = iomd; // save in SRB for later ->complete() call // ::initWithAddress() causes any previous contents of IOMD to be ::complete()'d if ( iomd->initWithAddress( srb, sizeof( SRB ), kIODirectionOutIn ) ) { iomd->prepare(); srb->srbPhys = (SRB *) iomd->getPhysicalAddress(); } else { // this should never happen, as we have allocated enough // IOMDs for MAX_SCSI_TARGETS plus 2 extra for reset and // a "fudge factor" just in case. panic( "Sym8xxSCSIController::resetCommand - IOMemoryDescriptor reinitialization failed" ); } srb->scsiCommand = scsiCommand; Sym8xxSCSIBusReset( srb ); }
//============================================================================== // IOHIDEventServiceUserClient::clientMemoryForType //============================================================================== IOReturn IOHIDEventServiceUserClient::clientMemoryForType( UInt32 type, IOOptionBits * options, IOMemoryDescriptor ** memory ) { IOReturn ret = kIOReturnNoMemory; if ( _queue ) { IOMemoryDescriptor * memoryToShare = _queue->getMemoryDescriptor(); // if we got some memory if (memoryToShare) { // Memory will be released by user client // when last map is destroyed. memoryToShare->retain(); ret = kIOReturnSuccess; } // set the result *options = 0; *memory = memoryToShare; } return ret; }
IOReturn SoftU2FUserClient::sendFrame(U2FHID_FRAME *frame, size_t frameSize) { SoftU2FDevice *device = nullptr; IOMemoryDescriptor *report = nullptr; if (isInactive()) return kIOReturnOffline; if (frameSize != HID_RPT_SIZE) return kIOReturnBadArgument; device = OSDynamicCast(SoftU2FDevice, getClient()); if (!device) return kIOReturnNotAttached; report = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, HID_RPT_SIZE); if (!report) return kIOReturnNoResources; report->writeBytes(0, frame, frameSize); if (device->handleReport(report) != kIOReturnSuccess) { report->release(); return kIOReturnError; } report->release(); return kIOReturnSuccess; }
void IOHIDTestDriver::issueFakeReport() { UInt8 report[][7] = { { 0x44, 0x3B, 0x49, 0x43, 0x80, 0x00, 0x00 }, { 0x44, 0x3B, 0x49, 0x43, 0x00, 0x00, 0x00 }, { 0x44, 0x3B, 0x49, 0x43, 0x20, 0x00, 0x00 }, { 0x44, 0x3B, 0x49, 0x43, 0x00, 0x00, 0x00 }, { 0x44, 0x3B, 0x49, 0x43, 0x10, 0x00, 0x00 }, { 0x44, 0x3B, 0x49, 0x43, 0x00, 0x00, 0x00 }, { 0x44, 0x3B, 0x49, 0x43, 0x00, 0x80, 0x00 }, { 0x44, 0x3B, 0x49, 0x43, 0x00, 0x00, 0x00 }, { 0x44, 0x36, 0x49, 0x43, 0x00, 0x00, 0x00 }, { 0x48, 0x19, 0x49, 0x43, 0x00, 0x00, 0x00 }, { 0x48, 0x15, 0x49, 0x43, 0x00, 0x00, 0x00 }, { 0x4C, 0x11, 0x49, 0x43, 0x00, 0x00, 0x00 } }; const UInt32 reportCount = sizeof(report)/sizeof(report[0]); static UInt32 reportIndex = 0; IOMemoryDescriptor * desc = IOMemoryDescriptor::withAddress( report[reportIndex], sizeof(report[0]), kIODirectionNone ); if (desc) { handleReport( desc ); desc->release(); } if ( ++reportIndex >= reportCount ) reportIndex = 0; }
IOReturn PAVirtualDeviceUserClient::clientMemoryForType(UInt32 type, UInt32 *flags, IOMemoryDescriptor **memory) { IOMemoryDescriptor *buf; debugIOLog("%s(%p)::%s clientMemoryForType %lu\n", getName(), this, __func__, (unsigned long) type); switch (type) { case kPAMemoryInputSampleData: buf = device->audioInputBuf; break; case kPAMemoryOutputSampleData: buf = device->audioOutputBuf; break; default: debugIOLog(" ... unsupported!\n"); return kIOReturnUnsupported; } if (buf) buf->retain(); *memory = buf; return kIOReturnSuccess; }
IOReturn IOFramebufferSharedUserClient::clientMemoryForType( UInt32 type, IOOptionBits * options, IOMemoryDescriptor ** memory ) { IOMemoryDescriptor * mem = 0; IOReturn err; switch (type) { case kIOFBCursorMemory: mem = owner->sharedCursor; mem->retain(); *options = kIOMapReadOnly; break; case kIOFBVRAMMemory: if (kIOReturnSuccess == clientHasPrivilege(current_task(), kIOClientPrivilegeLocalUser)) mem = owner->getVRAMRange(); break; } *memory = mem; if (mem) err = kIOReturnSuccess; else err = kIOReturnBadArgument; return (err); }
IOReturn IOHIDEventSystemUserClient::clientMemoryForType( UInt32 type, UInt32 * flags, IOMemoryDescriptor ** memory ) { IODataQueue * eventQueue = NULL; IOReturn ret = kIOReturnNoMemory; if (type == kIOHIDEventSystemKernelQueueID) eventQueue = kernelQueue; else eventQueue = copyDataQueueWithID(type); if ( eventQueue ) { IOMemoryDescriptor * desc = NULL; *flags = 0; desc = eventQueue->getMemoryDescriptor(); if ( desc ) { desc->retain(); ret = kIOReturnSuccess; } *memory = desc; if (type != kIOHIDEventSystemKernelQueueID) eventQueue->release(); } else { ret = kIOReturnBadArgument; } return ret; }
/* * GetSenseInformation * * Attempt to get SCSI sense information either from the Auto sense * mechanism or by querying manually. */ void IOSCSITape::GetSense(SCSITaskIdentifier request) { SCSI_Sense_Data senseBuffer = { 0 }; bool validSense = false; SCSIServiceResponse serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; IOMemoryDescriptor *bufferDesc = IOMemoryDescriptor::withAddress((void *)&senseBuffer, sizeof(senseBuffer), kIODirectionIn); if (GetTaskStatus(request) == kSCSITaskStatus_CHECK_CONDITION) { validSense = GetAutoSenseData(request, &senseBuffer); if (validSense == false) { if (REQUEST_SENSE(request, bufferDesc, kSenseDefaultSize, 0) == true) serviceResponse = SendCommand(request, kTenSecondTimeoutInMS); if (serviceResponse == kSCSIServiceResponse_TASK_COMPLETE) validSense = true; } if (validSense == true) InterpretSense(&senseBuffer); else STATUS_LOG("invalid or unretrievable SCSI SENSE"); } bufferDesc->release(); }
// Read a controller's queue IOMemoryDescriptor* WirelessGamingReceiver::ReadBuffer(int index) { IOMemoryDescriptor *data; data = OSDynamicCast(IOMemoryDescriptor, connections[index].inputArray->getObject(0)); if (data != NULL) data->retain(); connections[index].inputArray->removeObject(0); return data; }
IOMemoryDescriptor * AppleSamplePCI::copyGlobalMemory( void ) { IOMemoryDescriptor * memory; memory = fPCIDevice->getDeviceMemoryWithRegister( kIOPCIConfigBaseAddress0 ); if( memory) memory->retain(); return( memory ); }
void IOVideoSampleStream::postFreeInputBuffer(UInt64 vbiTime, UInt64 outputTime, UInt64 totalFrameCount, UInt64 droppedFrameCount,UInt64 lastDisplayedSequenceNumber) { IOStreamBuffer* buf = OSDynamicCast(IOStreamBuffer, _freeBuffers->getObject(0)); if (NULL == buf) { USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - no free buffers\n"); if ((getOutputQueue())->entryCount > 0) { //all the free buffers are in the queue already so just alert the host (void) sendOutputNotification(); } return; } _freeBuffers->removeObject(0); IOMemoryDescriptor *ctrlDescriptor = OSDynamicCast(IOMemoryDescriptor, buf->getControlBuffer()); if (NULL != ctrlDescriptor) { USBLog(1, "IOVideoSampleStream got control buffer descriptor\n"); SampleVideoDeviceControlBuffer theBuffControl, readBackControl; USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - passed in vbiTime = %lld outputTime = %lld framecount = %lld droppedframecount = %lld lastDisplayedSequenceNumber = %lld \n", vbiTime, outputTime, totalFrameCount, droppedFrameCount, lastDisplayedSequenceNumber); theBuffControl.vbiTime = vbiTime; theBuffControl.outputTime = outputTime; theBuffControl.totalFrameCount = totalFrameCount; theBuffControl.droppedFrameCount = droppedFrameCount; theBuffControl.firstVBITime = 0; theBuffControl.sequenceNumber = lastDisplayedSequenceNumber; theBuffControl.discontinuityFlags = 0; (void) ctrlDescriptor->prepare(); ctrlDescriptor->writeBytes(0, &theBuffControl, buf->getControlBuffer()->getLength()); ctrlDescriptor->readBytes(0, &readBackControl, buf->getControlBuffer()->getLength()); USBLog(1, "IOVideoSampleStream::postFreeInputBuffer - control buffer info vbiTime = %lld outputTime = %lld framecount = %lld droppedframecount = %lld sequencenumber = %lld\n", readBackControl.vbiTime, readBackControl.outputTime, readBackControl.totalFrameCount, readBackControl.droppedFrameCount,readBackControl.sequenceNumber); (void) ctrlDescriptor->complete(); } IOReturn result = enqueueOutputBuffer(buf, 0, buf->getDataBuffer()->getLength(), 0, buf->getControlBuffer()->getLength()); if (result != kIOReturnSuccess) { USBLog(1, "IOVideoSampleStream::postFreeInputBuffer help enqueueOutputBuffer failed! (%x)\n", result); return; } result = sendOutputNotification(); if (result != kIOReturnSuccess) { USBLog(1, "IOVideoSampleStream::postFreeInputBuffer help sendOutputNotification failed! (%x)\n", result); return; } }
// Received a normal HID update from the device void WirelessHIDDevice::receivedHIDupdate(unsigned char *data, int length) { IOReturn err; IOMemoryDescriptor *report; report = IOMemoryDescriptor::withAddress(data, length, kIODirectionNone); err = handleReport(report, kIOHIDReportTypeInput); report->release(); if (err != kIOReturnSuccess) IOLog("handleReport return: 0x%.8x\n", err); }
// Handle new data from the device void WirelessHIDDevice::receivedData(void) { IOMemoryDescriptor *data; WirelessDevice *device = OSDynamicCast(WirelessDevice, getProvider()); if (device == NULL) return; while ((data = device->NextPacket()) != NULL) { receivedMessage(data); data->release(); } }
IOReturn IOSCSITape::GetDeviceBlockLimits(void) { SCSITaskIdentifier task = NULL; IOReturn status = kIOReturnError; UInt8 blockLimitsData[6] = { 0 }; SCSITaskStatus taskStatus = kSCSITaskStatus_DeliveryFailure; IOMemoryDescriptor * dataBuffer = NULL; dataBuffer = IOMemoryDescriptor::withAddress(&blockLimitsData, sizeof(blockLimitsData), kIODirectionIn); require ((dataBuffer != 0), ErrorExit); task = GetSCSITask(); require ((task != 0), ErrorExit); if (READ_BLOCK_LIMITS(task, dataBuffer, 0x00) == true) taskStatus = DoSCSICommand(task, SCSI_NOMOTION_TIMEOUT); if (taskStatus == kSCSITaskStatus_GOOD) { // blkgran = blockLimitsData[0] & 0x1F; blkmin = (blockLimitsData[4] << 8) | blockLimitsData[5]; blkmax = (blockLimitsData[1] << 16) | (blockLimitsData[2] << 8) | blockLimitsData[3]; STATUS_LOG("min/max block size: %d/%d", blkmin, blkmax); status = kIOReturnSuccess; } ReleaseSCSITask(task); dataBuffer->release(); ErrorExit: return status; }
IOReturn XboxOneControllerDriver::sendHello() { IOReturn ior = kIOReturnSuccess; IOMemoryDescriptor* hello = nullptr; IOByteCount bytesWritten = 0; constexpr size_t helloSize = sizeof XboxOneControllerHelloMessage; if (_interruptPipe == nullptr) // paranoid check { IO_LOG_DEBUG("_interruptPipe is null"); ior = kIOReturnInternalError; goto cleanup; } // Create the hello message that we're about to send to the controller. hello = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, helloSize); if (hello == nullptr) { IO_LOG_DEBUG("Could not allocate buffer for hello message."); ior = kIOReturnNoMemory; goto cleanup; } bytesWritten = hello->writeBytes(0, XboxOneControllerHelloMessage, helloSize); if (bytesWritten != helloSize) // paranoid check { ior = kIOReturnOverrun; goto cleanup; } // Now send the message ior = _interruptPipe->Write(hello, 0, 0, hello->getLength()); if (ior != kIOReturnSuccess) { IO_LOG_DEBUG("Couldn't send hello message to controller: %08x\n", ior); goto cleanup; } cleanup: if (hello != nullptr) { hello->release(); } return ior; }
static inline bool hpetIsInvalid() { hpetInfo_t hpetInfo; hpet_get_info(&hpetInfo); // The AppleIntelCPUPowerManagement will crash if rcbaArea and/or HPET is NULL // Ordinarily this can never happen but modified xnu can allow for this. if(hpetInfo.rcbaArea == 0) { IOLog("Forcing takeover of AppleIntelCPUPowerManagement resource due to lack of RCBA (no LPC?)\n"); return true; } // Another case is that the LPC exists but the HPET isn't really valid. // That is to say that virtual hardware provides enough to get past xnu startup // but not enough to really make the HPET work. uint32_t hptc = *(uint32_t*)(hpetInfo.rcbaArea + 0x3404); if(!(hptc & hptcAE)) { IOLog("Forcing takeover of AppleIntelCPUPowerManagement resource because HPET is not enabled\n"); return true; } // Use the RCBA's HPTC to determine which of the four possible HPET physical addresses is used uint32_t hpetAreap = hpetAddr | ((hptc & 3) << 12); IOMemoryDescriptor *hpetMemDesc = IOMemoryDescriptor::withPhysicalAddress(hpetAreap, sizeof(hpetReg_t), kIODirectionIn); // grab the GCAP_ID (note offset is actually 0) uint64_t GCAP_ID; hpetMemDesc->readBytes(offsetof(hpetReg_t, GCAP_ID), &GCAP_ID, sizeof(GCAP_ID)); // We're done with the memory descriptor now, so release it hpetMemDesc->release(); hpetMemDesc = NULL; // Extract the VENDOR_ID_CAP field from the GCAP_ID and test it uint16_t vendorId = bitfield(GCAP_ID, 31, 16); if( (vendorId == 0x0000) || (vendorId == 0xffff)) { IOLog("Forcing takeover of AppleIntelCPUPowerManagement resource due to bad HPET VENDOR_ID_CAP\n"); return true; } else if(vendorId != 0x8086) { IOLog("WARNING: HPET is not Intel. Going ahead and allowing AppleIntelCPUPowerManagement to start but beware it may behave strangely\n"); } return false; }
int st_readwrite(dev_t dev, struct uio *uio, int ioflag) { IOSCSITape *st = IOSCSITape::devices[minor(dev)]; IOMemoryDescriptor *dataBuffer = IOMemoryDescriptorFromUIO(uio); int status = ENOSYS; IOReturn opStatus = kIOReturnError; int lastRealizedBytes = 0; if (dataBuffer == 0) return ENOMEM; dataBuffer->prepare(); opStatus = st->ReadWrite(dataBuffer, &lastRealizedBytes); dataBuffer->complete(); dataBuffer->release(); if (opStatus == kIOReturnSuccess) { uio_setresid(uio, uio_resid(uio) - lastRealizedBytes); if (st->blkno != -1) { if (st->IsFixedBlockSize()) st->blkno += (lastRealizedBytes / st->blksize); else st->blkno++; } status = KERN_SUCCESS; } else if (st->sense_flags & SENSE_FILEMARK) { if (st->fileno != -1) { st->fileno++; st->blkno = 0; } status = KERN_SUCCESS; } return status; }
IOReturn info_ennowelbers_syphon_proxyframebuffer_client::clientMemoryForType( UInt32 type, IOOptionBits * options, IOMemoryDescriptor ** memory ) { IOMemoryDescriptor *mem; switch(type) { case 0: mem=(IOMemoryDescriptor*)fProvider->buffer; break; case 1: mem=(IOMemoryDescriptor*)fProvider->fbuffer->cursorMem; break; } mem->retain(); if(mem==NULL) return kIOReturnError; *memory=mem; return kIOReturnSuccess; }
IOReturn IOSCSITape::SetDeviceDetails(SCSI_ModeSense_Default *modeData) { IOReturn status = kIOReturnError; IOMemoryDescriptor * dataBuffer = NULL; SCSITaskIdentifier task = NULL; SCSITaskStatus taskStatus = kSCSITaskStatus_DeviceNotResponding; dataBuffer = IOMemoryDescriptor::withAddress(modeData, sizeof(SCSI_ModeSense_Default), kIODirectionOut); require((dataBuffer != 0), ErrorExit); task = GetSCSITask(); require((task != 0), ErrorExit); if (MODE_SELECT_6(task, dataBuffer, 0x0, // PF 0x0, // SP sizeof(SCSI_ModeSense_Default), 0x00) == true) { taskStatus = DoSCSICommand(task, SCSI_NOMOTION_TIMEOUT); } if (taskStatus == kSCSITaskStatus_GOOD) { status = kIOReturnSuccess; } ReleaseSCSITask(task); dataBuffer->release(); ErrorExit: return status; }
IOReturn IOFramebufferUserClient::clientMemoryForType( UInt32 type, IOOptionBits * flags, IOMemoryDescriptor ** memory ) { static bool havePublishedResource; IOMemoryDescriptor * mem; IOReturn err; switch (type) { case kIOFBCursorMemory: if (!havePublishedResource) { havePublishedResource = true; publishResource("WindowServer"); } mem = owner->sharedCursor; mem->retain(); break; case kIOFBVRAMMemory: mem = owner->getVRAMRange(); break; default: mem = (IOMemoryDescriptor *) owner->userAccessRanges->getObject( type ); if (mem) mem->retain(); break; } *memory = mem; if (mem) err = kIOReturnSuccess; else err = kIOReturnBadArgument; return (err); }
IOReturn XboxOneControllerDriver::newReportDescriptor(IOMemoryDescriptor **descriptor) const { if (descriptor == nullptr) { return kIOReturnBadArgument; } constexpr size_t descriptorSize = sizeof XboxOneControllerReportDescriptor; IOMemoryDescriptor* buffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, descriptorSize); if (buffer == nullptr) { return kIOReturnNoMemory; } IOByteCount written = buffer->writeBytes(0, XboxOneControllerReportDescriptor, descriptorSize); if (written != sizeof XboxOneControllerReportDescriptor) // paranoid check { buffer->release(); return kIOReturnNoSpace; } *descriptor = buffer; return kIOReturnSuccess; }
IOReturn IOHIDEventSystemUserClient::clientMemoryForType( UInt32 type, UInt32 * flags, IOMemoryDescriptor ** memory ) { IODataQueue * eventQueue = OSDynamicCast(IODataQueue, (OSObject*)type); IOReturn ret = kIOReturnNoMemory; if ( eventQueue ) { IOMemoryDescriptor * desc = NULL; *flags = 0; desc = eventQueue->getMemoryDescriptor(); if ( desc ) { desc->retain(); ret = kIOReturnSuccess; } *memory = desc; } else { ret = kIOReturnBadArgument; } return ret; }
/* * GetDeviceDetails() * Get mode sense details and set device parameters. * * Would have ideally liked to use super::GetModeSense() but it appears * to set the DBD bit and we need the descriptor values for density, * etc. */ IOReturn IOSCSITape::GetDeviceDetails(void) { IOReturn status = kIOReturnError; SCSITaskIdentifier task = NULL; SCSITaskStatus taskStatus = kSCSITaskStatus_DeviceNotResponding; IOMemoryDescriptor * dataBuffer = NULL; SCSI_ModeSense_Default modeData = { 0 }; dataBuffer = IOMemoryDescriptor::withAddress(&modeData, sizeof(modeData), kIODirectionIn); require((dataBuffer != 0), ErrorExit); task = GetSCSITask(); require((task != 0), ErrorExit); if (MODE_SENSE_6(task, dataBuffer, 0x0, 0x0, 0x00, sizeof(SCSI_ModeSense_Default), 0x00) == true) { taskStatus = DoSCSICommand(task, SCSI_NOMOTION_TIMEOUT); } if (taskStatus == kSCSITaskStatus_GOOD) { /* copy mode data for next MODE SELECT */ bcopy(&modeData, &lastModeData, sizeof(SCSI_ModeSense_Default)); blksize = (modeData.descriptor.BLOCK_LENGTH[0] << 16) | (modeData.descriptor.BLOCK_LENGTH[1] << 8) | modeData.descriptor.BLOCK_LENGTH[2]; density = modeData.descriptor.DENSITY_CODE; flags &= ~(ST_READONLY | ST_BUFF_MODE); if (modeData.header.DEVICE_SPECIFIC_PARAMETER & SMH_DSP_WRITE_PROT) flags |= ST_READONLY; if (modeData.header.DEVICE_SPECIFIC_PARAMETER & SMH_DSP_BUFF_MODE) flags |= ST_BUFF_MODE; STATUS_LOG("density code: %d, %d-byte blocks, write-%s, %sbuffered", density, blksize, flags & ST_READONLY ? "protected" : "enabled", flags & ST_BUFF_MODE ? "" : "un"); status = kIOReturnSuccess; } ReleaseSCSITask(task); dataBuffer->release(); ErrorExit: return status; }
bool IOFWUserLocalIsochPort::initWithUserDCLProgram ( AllocateParams * params, IOFireWireUserClient & userclient, IOFireWireController & controller ) { // sanity checking if ( params->programExportBytes == 0 ) { ErrorLog ( "No program!" ) ; return false ; } fLock = IORecursiveLockAlloc () ; if ( ! fLock ) { ErrorLog ( "Couldn't allocate recursive lock\n" ) ; return false ; } // init easy params fUserObj = params->userObj ; fUserClient = & userclient ; fDCLPool = NULL ; fProgramCount = 0; fStarted = false ; IOReturn error = kIOReturnSuccess ; // get user program ranges: IOAddressRange * bufferRanges = new IOAddressRange[ params->bufferRangeCount ] ; if ( !bufferRanges ) { error = kIOReturnNoMemory ; } if ( !error ) { error = fUserClient->copyUserData(params->bufferRanges,(mach_vm_address_t)bufferRanges, sizeof ( IOAddressRange ) * params->bufferRangeCount ) ; } // create descriptor for program buffers IOMemoryDescriptor * bufferDesc = NULL ; if ( ! error ) { IOByteCount length = 0 ; for ( unsigned index = 0; index < params->bufferRangeCount; ++index ) { length += bufferRanges[ index ].length ; } bufferDesc = IOMemoryDescriptor::withAddressRanges ( bufferRanges, params->bufferRangeCount, kIODirectionOutIn, fUserClient->getOwningTask() ) ; if ( ! bufferDesc ) { error = kIOReturnNoMemory ; } else { // IOLog( "IOFWUserLocalIsochPort::initWithUserDCLProgram - checkMemoryInRange status 0x%08lx\n", checkMemoryInRange( bufferDesc, 0x000000001FFFFFFF ) ); error = bufferDesc->prepare( kIODirectionPrepareToPhys32 ) ; FWTrace( kFWTIsoch, kTPIsochPortUserInitWithUserDCLProgram, (uintptr_t)(fUserClient->getOwner()->getController()->getLink()), error, length, 0 ); // IOLog( "IOFWUserLocalIsochPort::initWithUserDCLProgram - prep 32 checkMemoryInRange status 0x%08lx\n", checkMemoryInRange( bufferDesc, 0x000000001FFFFFFF ) ); } } // create map for buffers; we will need to get a virtual address for them IOMemoryMap * bufferMap = NULL ; if ( !error ) { bufferMap = bufferDesc->map() ; if ( !bufferMap ) { DebugLog( "Couldn't map program buffers\n" ) ; error = kIOReturnVMError ; } bufferDesc->release() ; } IOMemoryDescriptor * userProgramExportDesc = NULL ; if ( !error ) { userProgramExportDesc = IOMemoryDescriptor::withAddressRange( params->programData, params->programExportBytes, kIODirectionOut, fUserClient->getOwningTask() ) ; } // get map of program export data if ( userProgramExportDesc ) { error = userProgramExportDesc->prepare() ; } if ( !error ) { DCLCommand * opcodes = NULL ; switch ( params->version ) { case kDCLExportDataLegacyVersion : error = importUserProgram( userProgramExportDesc, params->bufferRangeCount, bufferRanges, bufferMap ) ; ErrorLogCond( error, "importUserProgram returned %x\n", error ) ; if ( ! error ) { opcodes = (DCLCommand*)fProgramBuffer ; } break ; case kDCLExportDataNuDCLRosettaVersion : fDCLPool = fUserClient->getOwner()->getBus()->createDCLPool() ; if ( ! fDCLPool ) { error = kIOReturnNoMemory ; } if ( !error ) { error = fDCLPool->importUserProgram( userProgramExportDesc, params->bufferRangeCount, bufferRanges, bufferMap ) ; } fProgramBuffer = new UInt8[ sizeof( DCLNuDCLLeader ) ] ; { DCLNuDCLLeader * leader = (DCLNuDCLLeader*)fProgramBuffer ; { leader->pNextDCLCommand = NULL ; // unused - always NULL leader->opcode = kDCLNuDCLLeaderOp ; leader->program = fDCLPool ; } opcodes = (DCLCommand*)leader ; } break ; default : ErrorLog ( "unsupported DCL program type\n" ) ; error = kIOReturnBadArgument ; break ; } ErrorLogCond( !opcodes, "Couldn't get opcodes\n" ) ; IODCLProgram * program = NULL ; if ( opcodes ) { // IOFWLocalIsochPort::printDCLProgram( opcodes ) ; IOFireWireBus::DCLTaskInfoAux infoAux ; { infoAux.version = 2 ; infoAux.u.v2.bufferMemoryMap = bufferMap ; infoAux.u.v2.workloop = params->options & kFWIsochPortUseSeparateKernelThread ? createRealtimeThread() : NULL ; infoAux.u.v2.options = (IOFWIsochPortOptions)params->options ; } IOFireWireBus::DCLTaskInfo info = { 0, 0, 0, 0, 0, 0, & infoAux } ; program = fUserClient->getOwner()->getController()->getLink()->createDCLProgram( params->talking, opcodes, & info, params->startEvent, params->startState, params->startMask ) ; bufferMap->release() ; // retained by DCL program bufferMap = NULL ; if ( infoAux.u.v2.workloop ) { // If we created a custom workloop, it will be retained by the program... // We can release our reference... infoAux.u.v2.workloop->release() ; } DebugLogCond( !program, "createDCLProgram returned nil\n" ) ; } if ( program ) { if ( ! super::init( program, & controller ) ) { ErrorLog ( "IOFWUserIsochPort::init failed\n" ) ; error = kIOReturnError ; } } else { DebugLog ( "Couldn't create DCL program\n" ) ; error = kIOReturnNoMemory ; } userProgramExportDesc->complete() ; userProgramExportDesc->release() ; userProgramExportDesc = NULL ; } delete [] bufferRanges ; InfoLog( "-IOFWUserLocalIsochPort::initWithUserDCLProgram error=%x (build date "__TIME__" "__DATE__")\n", error ) ; return ( ! error ) ; }
// Processes a message for a controller void WirelessGamingReceiver::ProcessMessage(int index, const unsigned char *data, int length) { /* char s[1024]; int i; for (i = 0; i < length; i++) { s[(i * 2) + 0] = "0123456789ABCDEF"[(data[i] & 0xF0) >> 4]; s[(i * 2) + 1] = "0123456789ABCDEF"[data[i] & 0x0F]; } s[i * 2] = '\0'; IOLog("Got data (%d, %d bytes): %s\n", index, length, s); */ // Handle device connections if ((length == 2) && (data[0] == 0x08)) { if (data[1] == 0x00) { // Device disconnected // IOLog("process: Device detached\n"); if (connections[index].service != NULL) { connections[index].service->SetIndex(-1); if (connections[index].controllerStarted) connections[index].service->terminate(kIOServiceRequired | kIOServiceSynchronous); connections[index].service->detach(this); connections[index].service->release(); connections[index].service = NULL; connections[index].controllerStarted = false; } } else { // Device connected // IOLog("process: Attempting to add new device\n"); if (connections[index].service == NULL) { bool ready; int i, j; IOMemoryDescriptor *data; char c; ready = false; j = connections[index].inputArray->getCount(); for (i = 0; !ready && (i < j); i++) { data = OSDynamicCast(IOMemoryDescriptor, connections[index].inputArray->getObject(i)); data->readBytes(1, &c, 1); if (c == 0x0f) ready = true; } InstantiateService(index); if (ready) { // IOLog("Registering wireless device"); connections[index].controllerStarted = true; connections[index].service->registerService(); } } } return; } // Add anything else to the queue IOMemoryDescriptor *copy = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, length); copy->writeBytes(0, data, length); connections[index].inputArray->setObject(copy); if (connections[index].service == NULL) InstantiateService(index); if (connections[index].service != NULL) { connections[index].service->NewData(); if (!connections[index].controllerStarted) { char c; copy->readBytes(1, &c, 1); if (c == 0x0f) { // IOLog("Registering wireless device"); connections[index].controllerStarted = true; connections[index].service->registerService(); } } } copy->release(); }
bool X3100monitor::start(IOService * provider) { if (!provider || !super::start(provider)) return false; if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) { WarningLog("Can't locate fake SMC device, kext will not load"); return false; } IOMemoryDescriptor * theDescriptor; IOPhysicalAddress bar = (IOPhysicalAddress)((VCard->configRead32(kMCHBAR)) & ~0xf); DebugLog("Fx3100: register space=%08lx\n", (long unsigned int)bar); theDescriptor = IOMemoryDescriptor::withPhysicalAddress (bar, 0x2000, kIODirectionOutIn); // | kIOMapInhibitCache); if(theDescriptor != NULL) { mmio = theDescriptor->map(); if(mmio != NULL) { mmio_base = (volatile UInt8 *)mmio->getVirtualAddress(); #if DEBUG DebugLog(" MCHBAR mapped\n"); for (int i=0; i<0x2f; i +=16) { DebugLog("%04lx: ", (long unsigned int)i+0x1000); for (int j=0; j<16; j += 1) { DebugLog("%02lx ", (long unsigned int)INVID8(i+j+0x1000)); } DebugLog("\n"); } #endif } else { InfoLog(" MCHBAR failed to map\n"); return -1; } } char name[5]; //try to find empty key for (int i = 0; i < 0x10; i++) { snprintf(name, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, i); UInt8 length = 0; void * data = 0; IOReturn result = fakeSMC->callPlatformFunction(kFakeSMCGetKeyValue, true, (void *)name, (void *)&length, (void *)&data, 0); if (kIOReturnSuccess == result) { continue; } if (addSensor(name, TYPE_SP78, 2, i)) { numCard = i; break; } } if (kIOReturnSuccess != fakeSMC->callPlatformFunction(kFakeSMCAddKeyHandler, false, (void *)name, (void *)TYPE_SP78, (void *)2, this)) { WarningLog("Can't add key to fake SMC device, kext will not load"); return false; } return true; }
// // start // when this method is called, I have been selected as the driver for this device. // I can still return false to allow a different driver to load // bool local_IOath3kfrmwr::start(IOService *provider) { IOReturn err; const IOUSBConfigurationDescriptor *cd; // Do all the work here, on an IOKit matching thread. // 0.1 Get my USB Device DEBUG_LOG("%s(%p)::start!\n", getName(), this); pUsbDev = OSDynamicCast(IOUSBDevice, provider); if(!pUsbDev) { DEBUG_LOG("%s(%p)::start - Provider isn't a USB device!!!\n", getName(), this); return false; } // 0.2 Reset the device err = pUsbDev->ResetDevice(); if (err) { DEBUG_LOG("%s(%p)::start - failed to reset the device\n", getName(), this); pUsbDev->close(this); return false; } else IOLog("%s(%p)::start: device reset\n", getName(), this); // 0.3 Find the first config/interface int numconf = 0; if ((numconf = pUsbDev->GetNumConfigurations()) < 1) { DEBUG_LOG("%s(%p)::start - no composite configurations\n", getName(), this); return false; } else DEBUG_LOG("%s(%p)::start: num configurations %d\n", getName(), this, numconf); cd = pUsbDev->GetFullConfigurationDescriptor(0); // Set the configuration to the first config if (!cd) { DEBUG_LOG("%s(%p)::start - no config descriptor\n", getName(), this); return false; } // 1.0 Open the USB device if (!pUsbDev->open(this)) { DEBUG_LOG("%s(%p)::start - unable to open device for configuration\n", getName(), this); return false; } // 1.1 Set the configuration to the first config err = pUsbDev->SetConfiguration(this, cd->bConfigurationValue, true); if (err) { DEBUG_LOG("%s(%p)::start - unable to set the configuration\n", getName(), this); pUsbDev->close(this); return false; } DEBUG_LOG("%s(%p)::start - UPLOADED - %c\n", getName(), this,uploaded); //Uploading only one time if (!uploaded) { // 1.2 Get the status of the USB device (optional, for diag.) USBStatus status; err = pUsbDev->GetDeviceStatus(&status); if (err) { DEBUG_LOG("%s(%p)::start - unable to get device status\n", getName(), this); pUsbDev->close(this); return false; } else IOLog("%s(%p)::start: device status %d\n", getName(), this, (int)status); // 2.0 Find the interface for bulk endpoint transfers IOUSBFindInterfaceRequest request; request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; IOUSBInterface * intf = pUsbDev->FindNextInterface(NULL, &request); if (!intf) { DEBUG_LOG("%s(%p)::start - unable to find interface\n", getName(), this); pUsbDev->close(this); return false; } // 2.1 Open the interface if (!intf->open(this)) { DEBUG_LOG("%s(%p)::start - unable to open interface\n", getName(), this); pUsbDev->close(this); return false; } // 2.2 Get info on endpoints (optional, for diag.) int numep = intf->GetNumEndpoints(); DEBUG_LOG("%s(%p)::start: interface has %d endpoints\n", getName(), this, numep); UInt8 transferType = 0; UInt16 maxPacketSize = 0; UInt8 interval = 0; err = intf->GetEndpointProperties(0, 0x02, kUSBOut, &transferType, &maxPacketSize, &interval); if (err) { DEBUG_LOG("%s(%p)::start - failed to get endpoint 2 properties\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } else DEBUG_LOG("%s(%p)::start: EP2 %d %d %d\n", getName(), this, transferType, maxPacketSize, interval); err = intf->GetEndpointProperties(0, 0x01, kUSBIn, &transferType, &maxPacketSize, &interval); if (err) { DEBUG_LOG("%s(%p)::start - failed to get endpoint 1 properties\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } else {DEBUG_LOG("%s(%p)::start: EP1 %d %d %d\n", getName(), this, transferType, maxPacketSize, interval); } // 2.3 Get the pipe for bulk endpoint 2 Out IOUSBPipe * pipe = intf->GetPipeObj(0x02); if (!pipe) { DEBUG_LOG("%s(%p)::start - failed to find bulk out pipe\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } /* // TODO: Test the alternative way to do it: IOUSBFindEndpointRequest pipereq; pipereq.type = kUSBBulk; pipereq.direction = kUSBOut; pipereq.maxPacketSize = BULK_SIZE; pipereq.interval = 0; IOUSBPipe *pipe = intf->FindNextPipe(NULL, &pipereq); pipe = intf->FindNextPipe(pipe, &pipereq); if (!pipe) { DEBUG_LOG("%s(%p)::start - failed to find bulk out pipe 2\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } */ // 3.0 Send request to Control Endpoint to initiate the firmware transfer IOUSBDevRequest ctlreq; ctlreq.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBDevice); ctlreq.bRequest = USB_REQ_DFU_DNLOAD; ctlreq.wValue = 0; ctlreq.wIndex = 0; ctlreq.wLength = 20; ctlreq.pData = firmware_buf; #if 0 // Trying to troubleshoot the problem after Restart (with OSBundleRequired Root) for (int irep = 0; irep < 5; irep++) { // retry on error err = pUsbDev->DeviceRequest(&ctlreq); // (synchronous, will block) if (err) DEBUG_LOG("%s(%p)::start - failed to initiate firmware transfer (%d), retrying (%d)\n", getName(), this, err, irep+1); else break; } #else err = pUsbDev->DeviceRequest(&ctlreq); // (synchronous, will block) #endif if (err) { DEBUG_LOG("%s(%p)::start - failed to initiate firmware transfer (%d)\n", getName(), this, err); intf->close(this); pUsbDev->close(this); return false; } // 3.1 Create IOMemoryDescriptor for bulk transfers char buftmp[BULK_SIZE]; IOMemoryDescriptor * membuf = IOMemoryDescriptor::withAddress(&buftmp, BULK_SIZE, kIODirectionNone); if (!membuf) { DEBUG_LOG("%s(%p)::start - failed to map memory descriptor\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } err = membuf->prepare(); if (err) { DEBUG_LOG("%s(%p)::start - failed to prepare memory descriptor\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } // 3.2 Send the rest of firmware to the bulk pipe char * buf = firmware_buf; int size = sizeof(firmware_buf); buf += 20; size -= 20; int ii = 1; while (size) { int to_send = size < BULK_SIZE ? size : BULK_SIZE; memcpy(buftmp, buf, to_send); err = pipe->Write(membuf, 10000, 10000, to_send); if (err) { DEBUG_LOG("%s(%p)::start - failed to write firmware to bulk pipe (%d)\n", getName(), this, ii); intf->close(this); pUsbDev->close(this); return false; } buf += to_send; size -= to_send; ii++; } IOLog("%s(%p)::start: firmware was sent to bulk pipe\n", getName(), this); err = membuf->complete(); if (err) { DEBUG_LOG("%s(%p)::start - failed to complete memory descriptor\n", getName(), this); intf->close(this); pUsbDev->close(this); uploaded = false; return false; } /* // TODO: Test the alternative way to do it: IOMemoryDescriptor * membuf = IOMemoryDescriptor::withAddress(&firmware_buf[20], 246804-20, kIODirectionNone); // sizeof(firmware_buf) if (!membuf) { DEBUG_LOG("%s(%p)::start - failed to map memory descriptor\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } err = membuf->prepare(); if (err) { DEBUG_LOG("%s(%p)::start - failed to prepare memory descriptor\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } //err = pipe->Write(membuf); err = pipe->Write(membuf, 10000, 10000, 246804-20, NULL); if (err) { DEBUG_LOG("%s(%p)::start - failed to write firmware to bulk pipe\n", getName(), this); intf->close(this); pUsbDev->close(this); return false; } DEBUG_LOG("%s(%p)::start: firmware was sent to bulk pipe\n", getName(), this); */ // 4.0 Get device status (it fails, but somehow is important for operational device) err = pUsbDev->GetDeviceStatus(&status); if (err) { DEBUG_LOG("%s(%p)::start - unable to get device status\n", getName(), this); intf->close(this); pUsbDev->close(this); DEBUG_LOG("%s(%p)::start - Firmware Uploaded State Changed to - %c\n", getName(), this,uploaded); // Set the Upload State uploaded = true; return false; } else {DEBUG_LOG("%s(%p)::start: device status %d\n", getName(), this, (int)status); } // Close the interface intf->close(this); DEBUG_LOG("%s(%p)::start - Firmware Uploaded State Changed to - %c\n", getName(), this,uploaded); // Set the Upload State uploaded = true; } else { IOLog("%s(%p)::Firmware already uploaded\n", getName(), this); } // Close the USB device pUsbDev->close(this); return false; // return false to allow a different driver to load }
IOReturn SamplePCIUserClientClassName::method2( SampleStructForMethod2 * structIn, SampleResultsForMethod2 * structOut, IOByteCount inputSize, IOByteCount * outputSize ) { IOReturn err; IOMemoryDescriptor * memDesc = 0; UInt32 param1 = structIn->parameter1; uint64_t clientAddr = structIn->data_pointer; uint64_t size = structIn->data_length; // Rosetta if (fCrossEndian) { param1 = OSSwapInt32(param1); } IOLog("SamplePCIUserClient::method2(" UInt32_x_FORMAT ")\n", param1); IOLog( "fClientShared->string == \"%s\"\n", fClientShared->string ); structOut->results1 = 0x87654321; // Rosetta if (fCrossEndian) { structOut->results1 = OSSwapInt64(structOut->results1); clientAddr = OSSwapInt64(clientAddr); size = OSSwapInt64(size); } do { #if defined(__ppc__) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) // construct a memory descriptor for the out of line client memory // old 32 bit API - this will fail and log a backtrace if the task is 64 bit IOLog("The Pre-Leopard way to construct a memory descriptor\n"); memDesc = IOMemoryDescriptor::withAddress( (vm_address_t) clientAddr, (IOByteCount) size, kIODirectionNone, fTask ); if (memDesc == NULL) { IOLog("IOMemoryDescriptor::withAddress failed\n"); err = kIOReturnVMError; continue; } #else // 64 bit API - works on all tasks, whether 64 bit or 32 bit IOLog("The Leopard and later way to construct a memory descriptor\n"); memDesc = IOMemoryDescriptor::withAddressRange( clientAddr, size, kIODirectionNone, fTask ); if (memDesc == NULL) { IOLog("IOMemoryDescriptor::withAddresswithAddressRange failed\n"); err = kIOReturnVMError; continue; } #endif // Wire it and make sure we can write it err = memDesc->prepare( kIODirectionOutIn ); if (kIOReturnSuccess != err) { IOLog("IOMemoryDescriptor::prepare failed(0x%08x)\n", err); continue; } // Generate a DMA list for the client memory err = fDriver->generateDMAAddresses(memDesc); // Other methods to access client memory: // readBytes/writeBytes allow programmed I/O to/from an offset in the buffer char pioBuffer[ 200 ]; memDesc->readBytes(32, &pioBuffer, sizeof(pioBuffer)); IOLog("readBytes: \"%s\"\n", pioBuffer); // map() will create a mapping in the kernel address space. IOMemoryMap* memMap = memDesc->map(); if (memMap) { char* address = (char *) memMap->getVirtualAddress(); IOLog("kernel mapped: \"%s\"\n", address + 32); memMap->release(); } else { IOLog("memDesc map(kernel) failed\n"); } // this map() will create a mapping in the users (the client of this IOUserClient) address space. #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 memMap = memDesc->map(fTask, 0, kIOMapAnywhere); #else memMap = memDesc->createMappingInTask(fTask, 0, kIOMapAnywhere); #endif if (memMap) { #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 IOLog("The pre-Leopard way to construct a memory descriptor\n"); // old 32 bit API - this will truncate and log a backtrace if the task is 64 bit IOVirtualAddress address32 = memMap->getVirtualAddress(); IOLog("user32 mapped: " VirtAddr_FORMAT "\n", address32); #else IOLog("The Leopard and later way to construct a memory descriptor\n"); // new 64 bit API - same for 32 bit and 64 bit client tasks mach_vm_address_t address64 = memMap->getAddress(); IOLog("user64 mapped: 0x%016llx\n", address64); memMap->release(); #endif } else { IOLog("memDesc map(user) failed\n"); } // Done with the I/O now. memDesc->complete( kIODirectionOutIn ); } while ( false ); if (memDesc) memDesc->release(); return err; }
/** * Start this service. */ bool org_virtualbox_VBoxGuest::start(IOService *pProvider) { if (!IOService::start(pProvider)) return false; /* Low level initialization should be performed only once */ if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false)) { IOService::stop(pProvider); return false; } m_pIOPCIDevice = OSDynamicCast(IOPCIDevice, pProvider); if (m_pIOPCIDevice) { if (isVmmDev(m_pIOPCIDevice)) { /* Enable memory response from VMM device */ m_pIOPCIDevice->setMemoryEnable(true); m_pIOPCIDevice->setIOEnable(true); IOMemoryDescriptor *pMem = m_pIOPCIDevice->getDeviceMemoryWithIndex(0); if (pMem) { IOPhysicalAddress IOPortBasePhys = pMem->getPhysicalAddress(); /* Check that returned value is from I/O port range (at least it is 16-bit lenght) */ if((IOPortBasePhys >> 16) == 0) { RTIOPORT IOPortBase = (RTIOPORT)IOPortBasePhys; void *pvMMIOBase = NULL; uint32_t cbMMIO = 0; m_pMap = m_pIOPCIDevice->mapDeviceMemoryWithIndex(1); if (m_pMap) { pvMMIOBase = (void *)m_pMap->getVirtualAddress(); cbMMIO = m_pMap->getLength(); } int rc = VBoxGuestInitDevExt(&g_DevExt, IOPortBase, pvMMIOBase, cbMMIO, #if ARCH_BITS == 64 VBOXOSTYPE_MacOS_x64, #else VBOXOSTYPE_MacOS, #endif 0); if (RT_SUCCESS(rc)) { rc = VbgdDarwinCharDevInit(); if (rc == KMOD_RETURN_SUCCESS) { if (setupVmmDevInterrupts(pProvider)) { /* register the service. */ registerService(); LogRel(("VBoxGuest: IOService started\n")); return true; } LogRel(("VBoxGuest: Failed to set up interrupts\n")); VbgdDarwinCharDevRemove(); } else LogRel(("VBoxGuest: Failed to initialize character device (rc=%d).\n", rc)); VBoxGuestDeleteDevExt(&g_DevExt); } else LogRel(("VBoxGuest: Failed to initialize common code (rc=%d).\n", rc)); if (m_pMap) { m_pMap->release(); m_pMap = NULL; } } } else LogRel(("VBoxGuest: The device missing is the I/O port range (#0).\n")); } else