Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*-----------------------------------------------------------------------------*
 * 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;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
/*
 *  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;
}
Ejemplo n.º 11
0
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;
	}
}
Ejemplo n.º 13
0
// 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);
}
Ejemplo n.º 14
0
// 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();
    }
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
0
/*
 *  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();
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 30
0
/**
 * 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