예제 #1
0
파일: Sym8xxClient.cpp 프로젝트: OTiZ/osx
/*-----------------------------------------------------------------------------*
 * 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 );
}
예제 #2
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
예제 #3
0
파일: Sym8xxClient.cpp 프로젝트: OTiZ/osx
/*-----------------------------------------------------------------------------*
 *
 *-----------------------------------------------------------------------------*/
void Sym8xxSCSIController::executeCommand( IOSCSIParallelCommand *scsiCommand )
{
    SRB				*srb = NULL;
    SCSICDBInfo			scsiCDB;
    SCSITargetLun               targetLun;
    Nexus                       *nexus;
    Nexus                       *nexusPhys;  
    UInt32                      len;  
    bool                        isWrite;                
    IOMemoryDescriptor		* iomd;

    srb = (SRB *) scsiCommand->getCommandData();
    bzero( srb, sizeof(SRB) );

    srb->scsiCommand = scsiCommand;

    scsiCommand->getCDB( &scsiCDB );
    scsiCommand->getTargetLun( &targetLun );
    
    srb->target      = targetLun.target;
    srb->lun         = targetLun.lun;
    srb->srbCDBFlags = scsiCDB.cdbFlags;

    // 1 IOMD per target, since only 1 transaction possible with current architecture
    iomd             = SCSI_IOMDs[(int) srb->target ];
    srb->srbIOMD     = iomd;
    // ::initWithAddress() causes any previous IOMDs 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 1 extra for reset
	panic( "Sym8xxSCSIController::executeCommand - IOMemoryDescriptor reinitialization failed" );
    }

    /*
     * Setup the Nexus struct. This part of the SRB is read/written both by the
     * script and the driver.
     */

    nexus                     = &srb->nexus;
    nexusPhys                 = &srb->srbPhys->nexus;
    nexus->targetParms.target = srb->target;

//    printf( "SCSI(Symbios8xx): executeCommand: T/L = %d:%d Cmd = %08x CmdType = %d\n\r", 
//                        targetLun.target, targetLun.lun, (int)scsiCommand, scsiCommand->getCmdType() );
    
    switch ( scsiCommand->getCmdType() )
    {
        case kSCSICommandAbort:
        case kSCSICommandAbortAll:
        case kSCSICommandDeviceReset:
            Sym8xxAbortCommand( scsiCommand );
            return;

        default:
            ;
    }
    
    /*
     * Set client data buffer pointers in the SRB
     */
    scsiCommand->getPointers( &srb->xferDesc, &srb->xferCount, &isWrite );
    
    srb->directionMask = (isWrite) ? 0x00000000 :0x01000000;    
    
    nexus->cdb.ppData = OSSwapHostToLittleInt32((UInt32)&nexusPhys->cdbData);

    len = scsiCDB.cdbLength;

    nexus->cdb.length = OSSwapHostToLittleInt32( len );
    // implicit copying of arrays is not desireable.  explicitly spell out what is being copied
    // [rdar://problem/4092008]
    // nexus->cdbData    = scsiCDB.cdb;
    bcopy( &scsiCDB.cdb, &nexus->cdbData, sizeof( nexus->cdbData ) );

    Sym8xxCalcMsgs( scsiCommand );
    
    /*
     * Setup initial data transfer list (SGList) 
     */
    nexus->ppSGList   = (SGEntry *)OSSwapHostToLittleInt32((UInt32)&nexusPhys->sgListData[2]);
    Sym8xxUpdateSGList( srb );

    Sym8xxStartSRB( srb );
}
예제 #4
0
bool AppleSamplePCI::start( IOService * provider )
{
    IOMemoryDescriptor *	mem;
    IOMemoryMap *		map;

    IOLog("AppleSamplePCI::start\n");

    if( !super::start( provider ))
        return( false );

    /*
     * Our provider class is specified in the driver property table
     * as IOPCIDevice, so the provider must be of that class.
     * The assert is just to make absolutely sure for debugging.
     */

    assert( OSDynamicCast( IOPCIDevice, provider ));
    fPCIDevice = (IOPCIDevice *) provider;

    /*
     * Enable memory response from the card
     */
    fPCIDevice->setMemoryEnable( true );


    /*
     * Log some info about the device
     */

    /* print all the device's memory ranges */
    for( UInt32 index = 0;
         index < fPCIDevice->getDeviceMemoryCount();
         index++ ) {

        mem = fPCIDevice->getDeviceMemoryWithIndex( index );
        assert( mem );
        IOLog("Range[%ld] %08lx:%08lx\n", index,
              mem->getPhysicalAddress(), mem->getLength());
    }

    /* look up a range based on its config space base address register */
    mem = fPCIDevice->getDeviceMemoryWithRegister(
                                  kIOPCIConfigBaseAddress0 );
    if( mem )
        IOLog("Range@0x%x %08lx:%08lx\n", kIOPCIConfigBaseAddress0,
                mem->getPhysicalAddress(), mem->getLength());

    /* map a range based on its config space base address register,
     * this is how the driver gets access to its memory mapped registers
     * the getVirtualAddress() method returns a kernel virtual address
     * for the register mapping */
    
    map = fPCIDevice->mapDeviceMemoryWithRegister(
                                  kIOPCIConfigBaseAddress0 );
    if( map ) {
        IOLog("Range@0x%x (%08lx) mapped to kernel virtual address %08x\n",
                kIOPCIConfigBaseAddress0,
                map->getPhysicalAddress(),
                map->getVirtualAddress());
        /* release the map object, and the mapping itself */
        map->release();
    }

    /* read a config space register */
    IOLog("Config register@0x%x = %08lx\n", kIOPCIConfigCommand,
          fPCIDevice->configRead32(kIOPCIConfigCommand) );

    // construct a memory descriptor for a buffer below the 4Gb line &
    // so addressable by 32 bit DMA. This could be used for a 
    // DMA program buffer for example

    IOBufferMemoryDescriptor * bmd = 
	IOBufferMemoryDescriptor::inTaskWithPhysicalMask(
				// task to hold the memory
				kernel_task, 
				// options
				kIOMemoryPhysicallyContiguous, 
				// size
				64*1024, 
				// physicalMask - 32 bit addressable and page aligned
				0x00000000FFFFF000ULL);

    if (bmd) {
	generateDMAAddresses(bmd);
    } else {
	IOLog("IOBufferMemoryDescriptor::inTaskWithPhysicalMask failed\n");
    }
    fLowMemory = bmd;
    
    /* publish ourselves so clients can find us */
    registerService();

    return( true );
}