void FakeSMCDevice::ioWrite8( UInt16 offset, UInt8 value, IOMemoryMap * map )
{
    UInt16 base = 0;
	IODelay(10);
    if (map) base = map->getPhysicalAddress();
    
	if((base+offset) == APPLESMC_DATA_PORT) applesmc_io_data_writeb(status, base+offset, value);
	if((base+offset) == APPLESMC_CMD_PORT) applesmc_io_cmd_writeb(status, base+offset,value);
	//    outb( base + offset, value );
    //	if(((base+offset) != APPLESMC_DATA_PORT) && ((base+offset) != APPLESMC_CMD_PORT)) IOLog("iowrite8 to port %x.\n", base+offset);
    
	//HWSensorsDebugLog("iowrite8 called");
}
//
// Wait up to waittime seconds for the status bits to be set.
//
// Note that this spins, and should be avoided when possible.
//
bool
self::waitStatusBits(UInt32 bits, int waittime)
{
    UInt32	status_reg = 0;
    int		i;

    for (i = 0; i < (waittime * 100); i++) {
	status_reg = getStatusReg();
	if ((status_reg & bits) == bits)
	    return(true);
	IODelay(10000);
    }
    debug(2, "timed out waiting for status bits 0x%08x, have status 0x%08x",
	  (uint)bits, (uint)status_reg);
    return(false);
}
Exemplo n.º 3
0
WLCard::
WLCard(void* ioBase, void* klBase, IOService* parent) : _ioBase(ioBase),
                                     _keyLargoBase(klBase),
        			     _interrupts(0),
                                     _isEnabled(false),
                                      _parent(parent)
{
    _powerOn();
    IODelay(200 * 1000);
    _reset();

    /*
     * Get firmware vendor and version
     */
    WLIdentity ident;
    if (getIdentity(&ident) != kIOReturnSuccess) {
        WLLogErr("WLCard::WLCard: Couldn't read card identity\n");
        return;
    }

    WLLogNotice("WLCard: Firmware vendor %d, variant %d, version %d.%d\n",
                ident.vendor, ident.variant, ident.major, ident.minor);

    WLHardwareAddress macAddr;
    if (getHardwareAddress(&macAddr) != kIOReturnSuccess) {
        WLLogErr("WLCard::WLCard: Couldn't read MAC address\n");
        return;
    }
    
    _workLoop = _parent->getWorkLoop();
    if (!_workLoop) {
        WLLogErr("WLCard::WLCard: Failed to create workloop.\n");
        return;
    }
    
    _timedSendSource = IOTimerEventSource::timerEventSource(_parent, &WLCard::_myTimeoutHandler);
    if (!_timedSendSource) {
        WLLogErr("WLCard::WLCard: Failed to create timer event source.\n");
        return;
    }

    if (_workLoop->addEventSource(_timedSendSource) != kIOReturnSuccess) {
        WLLogErr("WLCard::WLCard: Failed to register timer event source.\n");
        return;
    }
}
Exemplo n.º 4
0
UInt64 CLASS::GetMicroFrameNumber(void)
{
	uint64_t counter1, counter2;
	uint32_t sts, mfIndex, count;
	sts = Read32Reg(&_pXHCIOperationalRegisters->USBSts);
	if (m_invalid_regspace || (sts & XHCI_STS_HCH))
		return 0ULL;
	/*
	 * TBD: For 32-bit compile, access to _millsecondCounter
	 *   is non-atomic, here vs FilterEventRing.
	 */
	for (count = 0U; count < 2U; ++count) {
		if (count)
			IODelay(126U);
		counter1 = _millsecondCounter;
		mfIndex = Read32Reg(&_pXHCIRuntimeRegisters->MFIndex);
		counter2 = _millsecondCounter;
		if (m_invalid_regspace)
			return 0ULL;
		if (counter1 != counter2) {
			/*
			 * Note: This can only happen if a primary
			 *   interrupt takes place between readings,
			 *   so use the 2nd reading and assume
			 *   MFIndex 0.
			 */
			return counter2 << 3;
		}
		mfIndex &= XHCI_MFINDEX_MASK;
		if (mfIndex)
			break;
		/*
		 * Note: XHCI allows controllers to halt the
		 *   clock if no device is connected.  Some,
		 *   such as the Renesas uPD720200a don't
		 *   generate timer interrupts when no device
		 *   is connected initially.  No need to delay.
		 */
		if (!counter1)
			break;
	}
	return (counter1 << 3) + mfIndex;
}
Exemplo n.º 5
0
UInt32 
AppleGenericPCATADriver::scanForDrives( void )
{
    UInt32 unitsFound;

    DLOG("%s::%s( %p )\n", getName(), __FUNCTION__, this);

    *_tfAltSDevCReg = mATADCRReset;

    IODelay( 100 );

    *_tfAltSDevCReg = 0x0;

    IOSleep( 10 );

    unitsFound = super::scanForDrives();

    *_tfSDHReg = 0x00;  // Initialize device selection to device 0.

    return unitsFound;
}
Exemplo n.º 6
0
void IOPlatformExpert::sleepKernel(void)
{
#if 0
  long cnt;
  boolean_t intState;
  
  intState = ml_set_interrupts_enabled(false);
  
  for (cnt = 0; cnt < 10000; cnt++) {
    IODelay(1000);
  }
  
  ml_set_interrupts_enabled(intState);
#else
//  PE_initialize_console(0, kPEDisableScreen);
  
  IOCPUSleepKernel();
  
//  PE_initialize_console(0, kPEEnableScreen);
#endif
}
int nouveau_therm_fan_rpm_get(struct nouveau_device *device)
{
	u32 cycles, cur, prev, stop = THERM_FAN_SENSE_CYCLES * 4 + 1;
	u64 start, interval;

	if (device->fan_tach.func != DCB_GPIO_UNUSED) {
        /* Time a complete rotation and extrapolate to RPM:
         * When the fan spins, it changes the value of GPIO FAN_SENSE.
         * We get 4 changes (0 -> 1 -> 0 -> 1) per complete rotation.
         */
        start = ptimer_read();

        prev = device->gpio_get(device, 0, device->fan_tach.func, device->fan_tach.line);
        cycles = 0;
        do {
            IODelay(750); /* supports 0 < rpm < 7500 */
            
            cur = device->gpio_get(device, 0, device->fan_tach.func, device->fan_tach.line);
            if (prev != cur) {
                if (!start)
                    start = ptimer_read();
                cycles++;
                prev = cur;
            }
            
            interval = ptimer_read() - start;
            
        } while (cycles < stop && interval < 500000000);
        
        if (interval) {
            return (int)(((u64)60000000000ULL * (((u64)cycles - 1) / 4)) / interval);
        } else
            return -EIO;
    }
    
    nv_debug(device, "DCB_GPIO_FAN_SENSE func not found\n");
    
    return -EIO;
}
Exemplo n.º 8
0
void udelay(unsigned int microseconds)
{
  // Spin delay for a number of microseconds
	IODelay(microseconds);
}
Exemplo n.º 9
0
void
xf86usleep(unsigned long usec)
    //unsigned long usec;
{
	IODelay(usec);
}
Exemplo n.º 10
0
IOReturn WLCard::_powerOn()
{
    /*
     * Magic monkey mojo gleamed from OpenBSD sources
     */

    /*
     * XXX: ???
     */
    UInt32 x;
    
    x = getKLRegister32(0x40);
    x |= 0x4;
    setKLRegister32(0x40, x);
    
    /*
     * Enable card slot.
     */
    setKLRegister(0x6a + 0x0f, 5);
    IODelay(10 * 1000);
    setKLRegister(0x6a + 0x0f, 4);
    IODelay(10 * 1000);

    /*
     * XXX: ???
     */
    x = getKLRegister32(0x40);
    x &= ~0x8000000;
    setKLRegister32(0x40, x);
    IODelay(10);
    setKLRegister(0x58 + 0xb, 0);
    IODelay(10);
    setKLRegister(0x58 + 0xa, 0x28);
    IODelay(10);
    setKLRegister(0x58 + 0xd, 0x28);
    IODelay(10);
    setKLRegister(0x6a + 0xd, 0x28);
    IODelay(10);
    setKLRegister(0x6a + 0xe, 0x28);
    IODelay(10);
    setKLRegister32(0x1c000, 0);
    IODelay(1 * 1000);
    
    /*
     * Initialize the card.
     */
    setKLRegister32(0x1a3e0, 0x41);
    IODelay(10);
    x = getKLRegister32(0x40);
    x |= 0x8000000;
    setKLRegister32(0x40, x);
    IODelay(100 * 1000);
    
    return kIOReturnSuccess;
}
Exemplo n.º 11
0
// Reset and enable the port
IOReturn
AppleUSBUHCI::RHResetPort(int port)
{
    UInt16 value;
    int i;
    
    USBLog(3, "AppleUSBUHCI[%p]::RHResetPort %d", this, port);
    port--; // convert 1-based to 0-based.

    value = ReadPortStatus(port) & kUHCI_PORTSC_MASK;
    WritePortStatus(port, value | kUHCI_PORTSC_RESET);
    
    /* Assert RESET for 50ms */
    IOSleep(50);
    
    value = ReadPortStatus(port) & kUHCI_PORTSC_MASK;
    WritePortStatus(port, value & ~kUHCI_PORTSC_RESET);
    
    IODelay(10);
    
    value = ReadPortStatus(port) & kUHCI_PORTSC_MASK;
    WritePortStatus(port, value | kUHCI_PORTSC_PED);
    
    for (i=10; i>0; i--) 
	{
        IOSleep(10);
        
        value = ReadPortStatus(port);
        
        if ((value & kUHCI_PORTSC_CCS) == 0) 
		{
            /* No device connected; don't enter reset state. */
            //USBLog(5, "%s[%p]: no device connected, not entering reset state");
            return kIOReturnNotResponding;
            break;
        }
        
        if (value & (kUHCI_PORTSC_PEDC | kUHCI_PORTSC_CSC)) 
		{
            /* Change bits detected. Clear them and continue waiting. */
            WritePortStatus(port, (value & kUHCI_PORTSC_MASK) | (kUHCI_PORTSC_PEDC | kUHCI_PORTSC_CSC));
            continue;
        }
        
        if (value & kUHCI_PORTSC_PED) 
		{
            /* Port successfully enabled. */
            break;
        }
        
    }
    
    if (i == 0) 
	{
        USBLog(5, "AppleUSBUHCI[%p]: reset port FAILED", this);
        return kIOReturnNotResponding;
    }
    
    // Remember that we were reset
    _portWasReset[port] = true;
    
    USBLog(5, "AppleUSBUHCI[%p]: reset port succeeded", this);
    return kIOReturnSuccess;
}
Exemplo n.º 12
0
UInt32 AppleIntelICHxSATA::scanForDrives( void )
{
    UInt32 unitsFound;

    // Try real hard to reset the port(s) and attached devices.

    for ( int loopMs = 0; loopMs <= 3000; loopMs += 10 )
    {
        if ( (loopMs % 1000) == 0 )
        {
            for ( UInt32 i = 0; i < _provider->getMaxDriveUnits(); i++ )
                _provider->setSerialATAPortEnableForDrive( i, false );
        
            IOSleep( 20 );
        
            for ( UInt32 i = 0; i < _provider->getMaxDriveUnits(); i++ )
                _provider->setSerialATAPortEnableForDrive( i, true );
    
            IOSleep( 20 );

            *_tfAltSDevCReg = mATADCRReset;  // ATA reset
    
            IODelay( 100 );
    
            *_tfAltSDevCReg = 0x0;            
        }

        if ( (*_tfStatusCmdReg & mATABusy) == 0x00 )
            break;

        IOSleep( 10 );
    }

    // ICH5 does offer a device present flag for each SATA port. This
    // information can be used to speed up boot by reducing unnecessary
    // bus scanning when no devices are present. In addition, the port
    // can be disabled to reduce power usage. For now we still use the
    // standard bus scanning implementation in IOATAController.

    unitsFound = IOPCIATA::scanForDrives();

    // Fixup discrepancies between the results from ATA bus scanning,
    // and the SATA device present status.

    for ( UInt32 unit = 0; unit < kMaxDrives; unit++ )
    {
        if ( _devInfo[unit].type != kUnknownATADeviceType &&
             ( unit >= _provider->getMaxDriveUnits() ||
               _provider->getSerialATAPortPresentStatusForDrive( unit ) == false ) )
        {
            // Detected a device, but SATA reports that no device are
            // present on the port. Trust SATA since if the device was
            // detected then surely the port present bit would be set.

            _devInfo[unit].type = kUnknownATADeviceType;
        }
    }

    // Turn off unused SATA ports.
    
    for ( UInt32 unit = 0; unit < _provider->getMaxDriveUnits(); unit++ )
    {
        if ( _devInfo[unit].type == kUnknownATADeviceType )
        {
            _provider->setSerialATAPortEnableForDrive( unit, false );
        }
    }

    return unitsFound;
}
Exemplo n.º 13
0
void UniNEnet::stopPHY()
{
    UInt32	  val32;
    UInt16	  i, val16;

    ELG( fWOL, fPHYType, '-Phy', "UniNEnet::stopPHY" );

    if ( !fBuiltin || (fPHYType == 0) )
        return;

    if ( fWOL == false )
    {   // disabling MIF interrupts on the 5201 is explicit
        if ( fPHYType == 0x5201 )
            miiWriteWord( 0x0000, MII_BCM5201_INTERRUPT );
    }

    /* Turn off PHY status-change polling to prevent immediate wakeup:	*/
    val32 = READ_REGISTER( MIFConfiguration );
    val32 &= ~kMIFConfiguration_Poll_Enable;
    WRITE_REGISTER( MIFConfiguration, val32 );

    if ( fWOL )
    {
        // For multicast filtering these bits must be enabled
        WRITE_REGISTER( RxMACConfiguration,		kRxMACConfiguration_Hash_Filter_Enable
                        | kRxMACConfiguration_Strip_FCS
                        | kRxMACConfiguration_Rx_Mac_Enable );

        UInt16	*p16;
        p16 = (UInt16*)myAddress.bytes;

        WRITE_REGISTER( WOLMagicMatch[ 2 ], p16[ 0 ] );		// enet address
        WRITE_REGISTER( WOLMagicMatch[ 1 ], p16[ 1 ] );
        WRITE_REGISTER( WOLMagicMatch[ 0 ], p16[ 2 ] );

        WRITE_REGISTER( WOLPatternMatchCount, kWOLPatternMatchCount_M | kWOLPatternMatchCount_N );

        val32 = kWOLWakeupCSR_Magic_Wakeup_Enable;		// Assume GMII
        if ( !(fXIFConfiguration & kXIFConfiguration_GMIIMODE) )
            val32 |= kWOLWakeupCSR_Mode_MII;			// NG - indicate non GMII
        WRITE_REGISTER( WOLWakeupCSR, val32 );
    }
    else
    {
        WRITE_REGISTER( RxMACConfiguration, 0 );
        IOSleep( 4 ); 		// it takes time for enable bit to clear
    }

    WRITE_REGISTER( TxMACConfiguration, 0 );
    WRITE_REGISTER( XIFConfiguration,	0 );

    fTxConfiguration &= ~kTxConfiguration_Tx_DMA_Enable;
    WRITE_REGISTER( TxConfiguration, fTxConfiguration );
    fRxConfiguration &= ~kRxConfiguration_Rx_DMA_Enable;
    WRITE_REGISTER( RxConfiguration, fRxConfiguration );

    if ( !fWOL )
    {
        // this doesn't power down stuff, but if we don't hit it then we can't
        // superisolate the transceiver
        WRITE_REGISTER( SoftwareReset, kSoftwareReset_TX | kSoftwareReset_RX );

        i = 0;
        do
        {
            IODelay( 10 );
            if ( i++ >= 100 )
            {
                ALRT( 0, val32, 'Sft-', "UniNEnet::stopPHY - timeout on SoftwareReset" );
                break;
            }
            val32 = READ_REGISTER( SoftwareReset );
        } while ( (val32 & (kSoftwareReset_TX | kSoftwareReset_RX)) != 0 );

        WRITE_REGISTER( TxMACSoftwareResetCommand, kTxMACSoftwareResetCommand_Reset );
        WRITE_REGISTER( RxMACSoftwareResetCommand, kRxMACSoftwareResetCommand_Reset );

        // This is what actually turns off the LINK LED

        switch ( fPHYType )
        {
        case 0x5400:
        case 0x5401:
#if 0
            // The 5400 has read/write privilege on this bit,
            // but 5201 is read-only.
            miiWriteWord( MII_CONTROL_POWERDOWN, MII_CONTROL );
#endif
            break;

        case 0x5221:
            // 1: enable shadow mode registers in 5221 (0x1A-0x1E)
            miiReadWord( &val16, MII_BCM5221_TestRegister );
            miiWriteWord( val16 | MII_BCM5221_ShadowRegEnableBit, MII_BCM5221_TestRegister );

            // 2: Force IDDQ mode for max power savings
            // remember..after setting IDDQ mode we have to "hard" reset
            // the PHY in order to access it.
            miiReadWord( &val16, MII_BCM5221_AuxiliaryMode4 );
            miiWriteWord( val16 | MII_BCM5221_SetIDDQMode, MII_BCM5221_AuxiliaryMode4 );
            break;

        case 0x5241:
            // 1: enable shadow register mode
            miiReadWord( &val16, MII_BCM5221_TestRegister );
            miiWriteWord( val16 | MII_BCM5221_ShadowRegEnableBit, MII_BCM5221_TestRegister );

            // 2: Set standby power bit
            miiReadWord( &val16, MII_BCM5221_AuxiliaryMode4 );
            miiWriteWord( val16 | MII_BCM5241_StandbyPowerMode, MII_BCM5221_AuxiliaryMode4 );
            break;

        case 0x5201:
#if 0
            miiReadWord( &val16, MII_BCM5201_AUXMODE2 );
            miiWriteWord( val16 & ~MII_BCM5201_AUXMODE2_LOWPOWER,  MII_BCM5201_AUXMODE2 );
#endif

            miiWriteWord( MII_BCM5201_MULTIPHY_SUPERISOLATE, MII_BCM5201_MULTIPHY );
            break;


        case 0x5411:
        case 0x5421:
        default:
            miiWriteWord( MII_CONTROL_POWERDOWN, MII_CONTROL );
            break;
        }/* end SWITCH on PHY type */

        /* Put the MDIO pins into a benign state.							*/
        /* Note that the management regs in the PHY will be inaccessible.	*/
        /* This is to guarantee max power savings on Powerbooks and			*/
        /* to eliminate damage to Broadcom PHYs.							*/

        WRITE_REGISTER( MIFConfiguration, kMIFConfiguration_BB_Mode );	// bit bang mode

        WRITE_REGISTER( MIFBitBangClock,		0x0000 );
        WRITE_REGISTER( MIFBitBangData,			0x0000 );
        WRITE_REGISTER( MIFBitBangOutputEnable, 0x0000 );
        WRITE_REGISTER( XIFConfiguration,		kXIFConfiguration_GMIIMODE
                        |  kXIFConfiguration_MII_Int_Loopback );
        val32 = READ_REGISTER( XIFConfiguration );	/// ??? make sure it takes.
    }// end of non-WOL case

    return;
}/* end stopPHY */
Exemplo n.º 14
0
bool AppleMacIO::selfTest( void )
{
    IODBDMADescriptor			*dmaDescriptors;
    UInt32				dmaDescriptorsPhys;
    UInt32				i;
    UInt32				status;
    IODBDMADescriptor			*dmaDesc;
    IOBufferMemoryDescriptor		*buffer;
    volatile IODBDMAChannelRegisters	*ioBaseDMA;
    bool				ok = false;
    enum { 				kTestChannel = 0x8000 };

    ioBaseDMA = (volatile IODBDMAChannelRegisters *)
		(((UInt32)fMemory->getVirtualAddress())
		+ kTestChannel );

    do {
	buffer = IOBufferMemoryDescriptor::withCapacity(page_size, kIODirectionOutIn, true);
	dmaDescriptors = (IODBDMADescriptor*)buffer->getBytesNoCopy();

        if (!dmaDescriptors)
	    continue;

        if ( (UInt32)dmaDescriptors & (page_size - 1) ) {
            IOLog("AppleMacIO::%s() - DMA Descriptor memory not page aligned!!", __FUNCTION__);
	    continue;
        }

        bzero( dmaDescriptors, page_size );

        IODBDMAReset( ioBaseDMA );

        dmaDesc = dmaDescriptors;

        IOMakeDBDMADescriptor( dmaDesc,
                            kdbdmaNop,
                            kdbdmaKeyStream0,
                            kdbdmaIntNever,
                            kdbdmaBranchNever,
                            kdbdmaWaitNever,
                            0,
                            0 );

        dmaDesc++;

	dmaDescriptorsPhys = (UInt32) (buffer->getPhysicalSegment(0, NULL, 0));

        IOMakeDBDMADescriptorDep( dmaDesc,
                                kdbdmaStoreQuad,
                                kdbdmaKeySystem,
                                kdbdmaIntNever,
                                kdbdmaBranchNever,
                                kdbdmaWaitNever,
                                4,
                                dmaDescriptorsPhys+16*sizeof(IODBDMADescriptor),
                                0x12345678 );

        dmaDesc++;

        IOMakeDBDMADescriptor( dmaDesc,
                            kdbdmaStop,
                            kdbdmaKeyStream0,
                            kdbdmaIntNever,
                            kdbdmaBranchNever,
                            kdbdmaWaitNever,
                            0,
                            0 );


        for ( i = 0; (!ok) && (i < 3); i++ )
        {
            dmaDescriptors[16].operation = 0;

            IOSetDBDMACommandPtr( ioBaseDMA, dmaDescriptorsPhys );
            IODBDMAContinue( ioBaseDMA );

            IODelay( 200 );

            status = IOGetDBDMAChannelStatus( ioBaseDMA );

            if ( ((status & kdbdmaActive) == 0)
                &&  ((status & kdbdmaDead) == 0)
                    && (OSReadSwapInt32( &dmaDescriptors[16].operation, 0 ) == 0x12345678 ))
                ok = true;
        }

        IODBDMAReset( ioBaseDMA );

    } while (false);

    if (buffer)
	    buffer->release();

    return ok;
}
Exemplo n.º 15
0
/*-----------------------------------------------------------------------------*
 * This routine initializes the script engine's register block.
 *
 *-----------------------------------------------------------------------------*/
bool Sym8xxSCSIController::Sym8xxInitChip()
{
    UInt32			i;

    /*
     * Reset the script engine
     */
    Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, RST );
    IODelay( 25 );
    Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, ISTAT_INIT );
  
    /*
     * Load our canned register values into the script engine
     */
    for ( i = 0; i < sizeof(Sym8xxInitRegs)/sizeof(ChipInitRegs); i++ )
    {
        Sym8xxWriteRegs( chipBaseAddr, Sym8xxInitRegs[i].regNum, Sym8xxInitRegs[i].regSize, Sym8xxInitRegs[i].regValue );
        IODelay( 10 );
    }

    /*
     * For hardware implementations that have a 40Mhz SCLK input, we enable the chip's on-board
     * clock doubler to bring the clock rate upto 80Mhz which is required for Ultra-SCSI timings.
     */
    if ( chipClockRate == CLK_40MHz )
    {
        /*
         *   Clock doubler setup for 875 (rev 3 and above).
         */
        /* set clock doubler enabler bit */
        Sym8xxWriteRegs( chipBaseAddr, STEST1, STEST1_SIZE, STEST1_INIT | DBLEN);
        IODelay(30);  
        /* halt scsi clock */
        Sym8xxWriteRegs( chipBaseAddr, STEST3, STEST3_SIZE, STEST3_INIT | HSC );
        IODelay(10);
        Sym8xxWriteRegs( chipBaseAddr, SCNTL3, SCNTL3_SIZE, SCNTL3_INIT_875);
        IODelay(10);
        /* set clock doubler select bit */
        Sym8xxWriteRegs( chipBaseAddr, STEST1, STEST1_SIZE, STEST1_INIT | DBLEN | DBLSEL);
        IODelay(10);
        /* clear hold on scsi clock */
        Sym8xxWriteRegs( chipBaseAddr, STEST3, STEST3_SIZE, STEST3_INIT);
    }

    /*  
     * Set our host-adapter ID in the script engine's registers
     */
    initiatorID = kHostAdapterSCSIId;

    if ( initiatorID > 7 )
    {
        Sym8xxWriteRegs( chipBaseAddr, RESPID1, RESPID1_SIZE, 1 << (initiatorID-8));
    }
    else
    {
        Sym8xxWriteRegs( chipBaseAddr, RESPID0, RESPID0_SIZE, 1 << initiatorID);
    }

    Sym8xxWriteRegs( chipBaseAddr, SCID, SCID_SIZE, SCID_INIT | initiatorID );

    return true;
}
Exemplo n.º 16
0
/*
 * Solaris delay is in ticks (hz) and Darwin uses microsecs
 * 1 HZ is 10 milliseconds
 */
void
osx_delay(int ticks)
{
	IODelay(ticks * 10000);
}
/* 
 * performExternalWordTransaction
 * 
 * Called by AppleSmartBatteryManagerUserClient
 */
IOReturn AppleSmartBatteryManager::performExternalTransaction( 
    void *in,
    void *out,
    IOByteCount inSize,
    IOByteCount *outSize)    
{
    uint16_t                i;
    uint16_t                retryAttempts = 0;
    IOSMBusTransaction      newTransaction;
    IOReturn                transactionSuccess;
    EXSMBUSInputStruct      *inSMBus = (EXSMBUSInputStruct *)in;
    EXSMBUSOutputStruct     *outSMBus = (EXSMBUSOutputStruct *)out;
    
    if (!inSMBus || !outSMBus) 
        return kIOReturnBadArgument;
    
    /* Attempt up to 5 transactions if we get failures
     */
    do {
        bzero(&newTransaction, sizeof(IOSMBusTransaction));    
    
        // Input: bus address
        if (kSMBusAppleDoublerAddr == inSMBus->batterySelector 
            || kSMBusBatteryAddr == inSMBus->batterySelector
            || kSMBusManagerAddr == inSMBus->batterySelector
            || kSMBusChargerAddr == inSMBus->batterySelector) 
        {
            newTransaction.address = inSMBus->batterySelector;
        } else {
            if (0 == inSMBus->batterySelector) 
            {
                newTransaction.address = kSMBusBatteryAddr;
            } else {
                newTransaction.address = kSMBusManagerAddr;
            }
        }
        
        // Input: command
        newTransaction.command = inSMBus->address;
    
        // Input: Read/Write Word/Block
        switch (inSMBus->type) {
            case kEXWriteWord:
                newTransaction.protocol = kIOSMBusProtocolWriteWord;
                newTransaction.sendDataCount = 2;
                break;
            case kEXReadWord:
                newTransaction.protocol = kIOSMBusProtocolReadWord;
                newTransaction.sendDataCount = 0;
                break;
            case kEXWriteBlock:
                newTransaction.protocol = kIOSMBusProtocolWriteBlock;
                // rdar://5433060 workaround for SMC SMBus blockCount bug
                // For block writes, clients always increment inByteCount +1 
                // greater than the actual byte count.
                // We decrement it here for IOSMBusController.
                newTransaction.sendDataCount = inSMBus->inByteCount - 1;
                break;
            case kEXReadBlock:
                newTransaction.protocol = kIOSMBusProtocolReadBlock;
                newTransaction.sendDataCount = 0;
                break;
            case kEXWriteByte:
                newTransaction.protocol = kIOSMBusProtocolWriteByte;
                newTransaction.sendDataCount = 1;
                break;
            case kEXReadByte:
                newTransaction.protocol = kIOSMBusProtocolReadByte;
                newTransaction.sendDataCount = 0;
                break;
            case kEXSendByte:
                newTransaction.protocol = kIOSMBusProtocolSendByte;
                newTransaction.sendDataCount = 0;
                break;
            default:
                return kIOReturnBadArgument;
        }
         
        // Input: copy data into transaction
        //  only need to copy data for write operations
        if ((kIOSMBusProtocolWriteWord == newTransaction.protocol)
             || (kIOSMBusProtocolWriteBlock == newTransaction.protocol))
        {
            for(i = 0; i<MAX_SMBUS_DATA_SIZE; i++) {
                newTransaction.sendData[i] = inSMBus->inBuf[i];    
            }
        }
    
    
        if (inSMBus->flags & kEXFlagRetry) 
        {
            if (retryAttempts >= kMaxRetries) {
                // Don't read off the end of the table...
                retryAttempts = kMaxRetries - 1;
            }
    
            // If this is a retry-on-failure, spin for a few microseconds
            IODelay( retryDelaysTable[retryAttempts] );
        }
    
        fManagerGate->runAction(
                            (IOCommandGate::Action)OSMemberFunctionCast(
                                IOCommandGate::Action, this, 
                                &AppleSmartBatteryManager::performExternalTransactionGated),
                           (void *)&newTransaction, 
                           (void *)&transactionSuccess, 
                           NULL, 
                           NULL);
    
    
        /* Output: status */
        if ((kIOReturnSuccess == transactionSuccess) 
            && (kIOSMBusStatusOK == newTransaction.status))
        {
            outSMBus->status = kIOReturnSuccess;
        } else {
            switch (newTransaction.status) {
                case kIOSMBusStatusUnknownFailure:
                case kIOSMBusStatusDeviceAddressNotAcknowledged:
                case kIOSMBusStatusDeviceError:
                case kIOSMBusStatusDeviceCommandAccessDenied:
                case kIOSMBusStatusUnknownHostError:
                    outSMBus->status = kIOReturnNoDevice;
                    break;
                case kIOSMBusStatusTimeout:
                case kIOSMBusStatusBusy:
                    outSMBus->status = kIOReturnTimeout;                
                    break;
                case kIOSMBusStatusHostUnsupportedProtocol:
                    outSMBus->status = kIOReturnUnsupported;
                    break;
                default:
                    outSMBus->status = kIOReturnInternalError;
                    break;
           }
        }

    /* Retry this transaction if we received a failure
     */
    } while ((inSMBus->flags & kEXFlagRetry) 
          && (outSMBus->status != kIOReturnSuccess) 
          && (++retryAttempts < kMaxRetries));


    /* Output: read word/read block results */    
    if (((kIOSMBusProtocolReadWord == newTransaction.protocol)
         || (kIOSMBusProtocolReadBlock == newTransaction.protocol)
         || (kIOSMBusProtocolReadByte == newTransaction.protocol))
        && (kIOSMBusStatusOK == newTransaction.status))
    {
        outSMBus->outByteCount = newTransaction.receiveDataCount;
        
        for(i = 0; i<outSMBus->outByteCount; i++) {
            outSMBus->outBuf[i] = newTransaction.receiveData[i];    
        }
    }

    return kIOReturnSuccess;
}