예제 #1
0
static VOID
XenPci_HighSyncCallFunction0(
  PRKDPC Dpc,
  PVOID Context,
  PVOID SystemArgument1,
  PVOID SystemArgument2)
{
  highsync_info_t *highsync_info = Context;
  ULONG ActiveProcessorCount;
  KIRQL old_irql;
  
  UNREFERENCED_PARAMETER(Dpc);
  UNREFERENCED_PARAMETER(SystemArgument1);
  UNREFERENCED_PARAMETER(SystemArgument2);

  FUNCTION_ENTER();
#if (NTDDI_VERSION >= NTDDI_WINXP)
  ActiveProcessorCount = (ULONG)KeNumberProcessors;
#else
  ActiveProcessorCount = (ULONG)*KeNumberProcessors;
#endif
  InterlockedIncrement(&highsync_info->nr_procs_at_dispatch_level);
  if (highsync_info->sync_level > DISPATCH_LEVEL)
  {
    while (highsync_info->nr_procs_at_dispatch_level < (LONG)ActiveProcessorCount)
    {
      KeStallExecutionProcessor(1);
      KeMemoryBarrier();
    }
  }
  _disable(); //__asm cli;  
  KeRaiseIrql(highsync_info->sync_level, &old_irql);
  while (highsync_info->nr_spinning_at_sync_level < (LONG)ActiveProcessorCount - 1)
  {
    KeStallExecutionProcessor(1);
    KeMemoryBarrier();
  }
  highsync_info->function0(highsync_info->context);
  KeLowerIrql(old_irql);
  _enable(); //__asm sti;
  highsync_info->do_spin = FALSE;
  KeMemoryBarrier();  
  /* wait for all the other processors to complete spinning, just in case it matters */
  while (highsync_info->nr_spinning_at_sync_level)
  {
    KeStallExecutionProcessor(1);
    KeMemoryBarrier();
  }
  InterlockedDecrement(&highsync_info->nr_procs_at_dispatch_level);
  /* wait until nr_procs_at_dispatch_level drops to 0 indicating that nothing else requires highsync_info */
  while (highsync_info->nr_procs_at_dispatch_level)
  {
    KeStallExecutionProcessor(1);
    KeMemoryBarrier();
  }
  KeSetEvent(&highsync_info->highsync_complete_event, IO_NO_INCREMENT, FALSE);

  FUNCTION_EXIT();
}
예제 #2
0
파일: inbv.c 프로젝트: hoangduit/reactos
static VOID
NTAPI
BootImageFadeIn(VOID)
{
    UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)];
    PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer;
    LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER));

    ULONG Iteration, Index, ClrUsed;

    /* Check if we're installed and we own it */
    if ((InbvBootDriverInstalled) &&
        (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
    {
        /* Acquire the lock */
        InbvAcquireLock();

        /*
         * Build a bitmap containing the fade in palette. The palette entries
         * are then processed in a loop and set using VidBitBlt function.
         */
        ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]);
        RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER));
        PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER);
        PaletteBitmap->biBitCount = 4;
        PaletteBitmap->biClrUsed = ClrUsed;

        /*
         * Main animation loop.
         */
        for (Iteration = 0; Iteration <= PALETTE_FADE_STEPS; ++Iteration)
        {
            for (Index = 0; Index < ClrUsed; Index++)
            {
                Palette[Index].rgbRed = (UCHAR)
                    (_MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS);
                Palette[Index].rgbGreen = (UCHAR)
                    (_MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS);
                Palette[Index].rgbBlue = (UCHAR)
                    (_MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS);
            }

            VidBitBlt(PaletteBitmapBuffer, 0, 0);

            /* Wait for a bit. */
            KeStallExecutionProcessor(PALETTE_FADE_TIME);
        }

        /* Release the lock */
        InbvReleaseLock();

        /* Wait for a bit. */
        KeStallExecutionProcessor(PALETTE_FADE_TIME);
    }
}
예제 #3
0
static VOID
XenPci_HighSyncCallFunctionN(
  PRKDPC Dpc,
  PVOID Context,
  PVOID SystemArgument1,
  PVOID SystemArgument2)
{
  highsync_info_t *highsync_info = Context;
  ULONG ActiveProcessorCount;
  KIRQL old_irql;
  
  UNREFERENCED_PARAMETER(Dpc);
  UNREFERENCED_PARAMETER(SystemArgument1);
  UNREFERENCED_PARAMETER(SystemArgument2);

  FUNCTION_ENTER();
  FUNCTION_MSG("(CPU = %d)\n", KeGetCurrentProcessorNumber());

  KdPrint((__DRIVER_NAME "     CPU %d spinning...\n", KeGetCurrentProcessorNumber()));
  InterlockedIncrement(&highsync_info->nr_procs_at_dispatch_level);
  if (highsync_info->sync_level > DISPATCH_LEVEL)
  {
#if (NTDDI_VERSION >= NTDDI_WINXP)
    ActiveProcessorCount = (ULONG)KeNumberProcessors;
#else
    ActiveProcessorCount = (ULONG)*KeNumberProcessors;
#endif
    while (highsync_info->nr_procs_at_dispatch_level < (LONG)ActiveProcessorCount)
    {
      KeStallExecutionProcessor(1);
      KeMemoryBarrier();
    }
  }
  _disable(); //__asm cli;  
  KeRaiseIrql(highsync_info->sync_level, &old_irql);
  InterlockedIncrement(&highsync_info->nr_spinning_at_sync_level);
  while(highsync_info->do_spin)
  {
    KeStallExecutionProcessor(1);
    KeMemoryBarrier();
  }
  highsync_info->functionN(highsync_info->context);
  KeLowerIrql(old_irql);
  _enable(); //__asm sti;
  InterlockedDecrement(&highsync_info->nr_spinning_at_sync_level);
  InterlockedDecrement(&highsync_info->nr_procs_at_dispatch_level);
  FUNCTION_EXIT();
  return;
}
예제 #4
0
파일: synth.c 프로젝트: BillTheBest/WinNT4
VOID
SynthMidiSendFM(
    IN    PUCHAR PortBase,
    IN    ULONG Address,
    IN    UCHAR Data
)
{
    // these delays need to be 23us at least for old opl2 chips, even
    // though new chips can handle 1 us delays.

    WRITE_PORT_UCHAR(PortBase + (Address < 0x100 ? 0 : 2), (UCHAR)Address);
    KeStallExecutionProcessor(23);
    WRITE_PORT_UCHAR(PortBase + (Address < 0x100 ? 1 : 3), Data);
    KeStallExecutionProcessor(23);
}
예제 #5
0
/*
 * FUNCTION: Write data to a port, waiting first for it to become ready
 */
BOOLEAN
i8042Write(
	IN PPORT_DEVICE_EXTENSION DeviceExtension,
	IN PUCHAR addr,
	IN UCHAR data)
{
	ULONG Counter;

	ASSERT(addr);
	ASSERT(DeviceExtension->ControlPort != NULL);

	Counter = DeviceExtension->Settings.PollingIterations;

	while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) &&
	       (Counter--))
	{
		KeStallExecutionProcessor(50);
	}

	if (Counter)
	{
		WRITE_PORT_UCHAR(addr, data);
		INFO_(I8042PRT, "Sent 0x%x to port %p\n", data, addr);
		return TRUE;
	}
	return FALSE;
}
예제 #6
0
파일: common.cpp 프로젝트: GYGit/reactos
void CCMIAdapter::resetController()
{
	PAGED_CODE();
	DBGPRINT(("CCMIAdapter[%p]::resetController()", this));

	writeUInt32(REG_INTHLDCLR, 0);

#if OUT_CHANNEL == 1
	writeUInt32(REG_FUNCTRL0, ADC_CH0 | (RST_CH0 | RST_CH1));
	writeUInt32(REG_FUNCTRL0, ADC_CH0 & ~(RST_CH0 | RST_CH1));
#else
	writeUInt32(REG_FUNCTRL0, ADC_CH1 | (RST_CH0 | RST_CH1));
	writeUInt32(REG_FUNCTRL0, ADC_CH1 & ~(RST_CH0 | RST_CH1));
#endif
	KeStallExecutionProcessor(100L);

	writeUInt32(REG_FUNCTRL0, 0);
	writeUInt32(REG_FUNCTRL1, 0);

	writeUInt32(REG_CHFORMAT, 0);
	writeUInt32(REG_MISCCTRL, EN_DBLDAC);
#if OUT_CHANNEL == 1
	setUInt32Bit(REG_MISCCTRL, XCHG_DAC);
#endif

	setUInt32Bit(REG_FUNCTRL1, BREQ);

	writeMixer(0, 0);

	return;
}
예제 #7
0
VOID ShiftOutBits(
    IN PFDO_DATA FdoData,
    IN USHORT data,
    IN USHORT count,
    IN PUCHAR CSRBaseIoAddress)
{
    USHORT x,mask;

    mask = 0x01 << (count - 1);
    x = FdoData->ReadPort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG));

    x &= ~(EEDO | EEDI);

    do
    {
        x &= ~EEDI;
        if(data & mask)
            x |= EEDI;

        FdoData->WritePort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG), x);
        KeStallExecutionProcessor(100);
        RaiseClock(FdoData, &x, CSRBaseIoAddress);
        LowerClock(FdoData, &x, CSRBaseIoAddress);
        mask = mask >> 1;
    } while(mask);

    x &= ~EEDI;
    FdoData->WritePort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG), x);
}
예제 #8
0
static void vdev_sleep(void *context, unsigned int msecs)
{
    UNREFERENCED_PARAMETER(context);

    /* We can't really sleep in a storage miniport so we just busy wait. */
    KeStallExecutionProcessor(1000 * msecs);
}
예제 #9
0
파일: pxe.c 프로젝트: ariscop/reactos
BOOLEAN CallPxe(UINT16 Service, PVOID Parameter)
{
    PPXE pxe;
    PXENV_EXIT exit;

    pxe = GetPxeStructure();
    if (!pxe)
        return FALSE;

    if (Service != PXENV_TFTP_READ)
    {
        // HACK: this delay shouldn't be necessary
        KeStallExecutionProcessor(100 * 1000); // 100 ms
        TRACE("PxeCall(0x%x, %p)\n", Service, Parameter);
    }

    exit = PxeCallApi(pxe->EntryPointSP.segment, pxe->EntryPointSP.offset, Service, Parameter);
    if (exit != PXENV_EXIT_SUCCESS)
    {
        ERR("PxeCall(0x%x, %p) failed with exit=%d status=0x%x\n",
                Service, Parameter, exit, *(PXENV_STATUS*)Parameter);
        return FALSE;
    }
    if (*(PXENV_STATUS*)Parameter != PXENV_STATUS_SUCCESS)
    {
        ERR("PxeCall(0x%x, %p) succeeded, but returned error status 0x%x\n",
                Service, Parameter, *(PXENV_STATUS*)Parameter);
        return FALSE;
    }
    return TRUE;
}
예제 #10
0
static FORCEINLINE NTSTATUS
__WaitState2(
    IN  PCHAR                   BackendPath,
    IN OUT PXENBUS_STATE        State
    )
{
    NTSTATUS        Status;
    PCHAR           Buffer;
    XENBUS_STATE    OldState = *State;

    while (OldState == *State) {
        Status = StoreRead(NULL, BackendPath, "state", &Buffer);
        if (!NT_SUCCESS(Status))
            goto fail;
        *State = (XENBUS_STATE)strtoul(Buffer, NULL, 10);
        AustereFree(Buffer);

        if (*State == OldState)
            KeStallExecutionProcessor(100000);
    }

    LogTrace("BACKEND_STATE  -> %s\n", __XenbusStateName(*State));
    return STATUS_SUCCESS;

fail:
    return Status;
}
예제 #11
0
파일: synth.c 프로젝트: BillTheBest/WinNT4
BOOLEAN
SynthPresent(PUCHAR base, PUCHAR inbase, volatile BOOLEAN *Fired)
/*++

Routine Description:

    Detect the presence or absence of a 3812 (adlib-compatible) synthesizer
    at the given i/o address by starting the timer and looking for an
    overflow. Can be used to detect left and right synthesizers separately.

Arguments:

    base - base output address
    inbase - base input address

Return Value:

    TRUE if a synthesizer is present at that address

--*/
{
#define inport(port)    READ_PORT_UCHAR((PUCHAR)(port))

        UCHAR t1, t2;

        if (Fired) {
            *Fired = FALSE;
        }

        // check if the chip is present
        SynthMidiSendFM(base, 4, 0x60);             // mask T1 & T2
        SynthMidiSendFM(base, 4, 0x80);             // reset IRQ
        t1 = inport(inbase);                        // read status register
        SynthMidiSendFM(base, 2, 0xff);             // set timer - 1 latch

        SynthMidiSendFM(base, 4, 0x21);             // unmask & start T1

        // this timer should go off in 80 us. It sometimes
        // takes more than 100us, but will always have expired within
        // 200 us if it is ever going to.
        KeStallExecutionProcessor(200);

        if (Fired && *Fired) {
            return TRUE;
        }

        t2 = inport(inbase);                        // read status register

        SynthMidiSendFM(base, 4, 0x60);
        SynthMidiSendFM(base, 4, 0x80);

        if (!((t1 & 0xE0) == 0) || !((t2 & 0xE0) == 0xC0)) {
            return(FALSE);
        }

        return TRUE;

#undef inport

}
예제 #12
0
VOID LowerClock(
    IN PFDO_DATA FdoData,
    IN OUT USHORT *x,
    IN PUCHAR CSRBaseIoAddress)
{
    *x = *x & ~EESK;
    FdoData->WritePort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG), *x);
    KeStallExecutionProcessor(100);
}
예제 #13
0
BOOLEAN
mpuWrite(
    PSOUND_HARDWARE pHw,
    UCHAR value
)
/*++

Routine Description:

    Write a command or data to the MPU

Arguments:

    pHw - Pointer to the device extension data
    value - the value to be written

Return Value:

    TRUE if written correctly , FALSE otherwise

--*/
{
    ULONG uCount;

    ASSERT(pHw->Key == HARDWARE_KEY);

    uCount = 100;

    while (uCount--) {
        int InnerCount;

        HwEnter(pHw);

        //
        // Inner count loop protects against dynamic deadlock with
        // midi.
        //

        for (InnerCount = 0; InnerCount < 10; InnerCount++) {
            if (!(INPORT(pHw, MPU_STATUS_PORT) & 0x40)) {  // is it ok to send data (bit 6 clear)? - drude
                OUTPORT(pHw, MPU_DATA_PORT, value);
                break;
            }
            KeStallExecutionProcessor(1); // 1 us
        }

        HwLeave(pHw);

        if (InnerCount < 10) {
            return TRUE;
        }
    }

    dprintf1(("mpuWrite:Failed to write %x to mpu", (ULONG)value));

    return FALSE;
}
예제 #14
0
VOID
i8042Flush(
	IN PPORT_DEVICE_EXTENSION DeviceExtension)
{
	UCHAR Ignore;

	/* Flush output buffer */
	while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF /* | MOU_OBF*/, &Ignore))) {
		KeStallExecutionProcessor(50);
		TRACE_(I8042PRT, "Output data flushed\n");
	}

	/* Flush input buffer */
	while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_IBF, &Ignore))) {
		KeStallExecutionProcessor(50);
		TRACE_(I8042PRT, "Input data flushed\n");
	}
}
예제 #15
0
static void
ChipSelOn(void)
{
    ConsoleLedState = *CpuAuxControl & CONSOLE_LED;

    *CpuAuxControl &= ~CPU_TO_SER;
    *CpuAuxControl &= ~SERCLK;
    *CpuAuxControl &= ~NVRAM_PRE;
    KeStallExecutionProcessor(1);
    *CpuAuxControl |= CONSOLE_CS;
    *CpuAuxControl |= SERCLK;
}
예제 #16
0
파일: scsiport.c 프로젝트: mvardan/reactos
static
BOOLEAN
SpiSendSynchronousSrb(
    IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
    IN PSCSI_REQUEST_BLOCK Srb)
{
    BOOLEAN ret;

    ASSERT(!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE));

    /* HACK: handle lack of interrupts */
    while (!(DeviceExtension->InterruptFlags & SCSI_PORT_NEXT_REQUEST_READY))
    {
        KeStallExecutionProcessor(100 * 1000);
        DeviceExtension->HwInterrupt(DeviceExtension->MiniPortDeviceExtension);
    }

    DeviceExtension->InterruptFlags &= ~SCSI_PORT_NEXT_REQUEST_READY;
    Srb->SrbFlags |= SRB_FLAGS_IS_ACTIVE;

    if (!DeviceExtension->HwStartIo(
            DeviceExtension->MiniPortDeviceExtension,
            Srb))
    {
        ExFreePool(Srb);
        return FALSE;
    }

    /* HACK: handle lack of interrupts */
    while (Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE)
    {
        KeStallExecutionProcessor(100 * 1000);
        DeviceExtension->HwInterrupt(DeviceExtension->MiniPortDeviceExtension);
    }

    ret = SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS;
    ExFreePool(Srb);

    return ret;
}
예제 #17
0
static NTSTATUS
i8042BasicDetect(
    IN PPORT_DEVICE_EXTENSION DeviceExtension)
{
    NTSTATUS Status;
    ULONG ResendIterations;
    UCHAR Value = 0;

    /* Don't enable keyboard and mouse interrupts, disable keyboard/mouse */
    i8042Flush(DeviceExtension);
    if (!i8042ChangeMode(DeviceExtension, CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB, CCB_KBD_DISAB | CCB_MOUSE_DISAB))
        return STATUS_IO_DEVICE_ERROR;

    i8042Flush(DeviceExtension);

    /* Issue a CTRL_SELF_TEST command to check if this is really an i8042 controller */
    ResendIterations = DeviceExtension->Settings.ResendIterations + 1;
    while (ResendIterations--)
    {
        if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST))
        {
            WARN_(I8042PRT, "Writing CTRL_SELF_TEST command failed\n");
            return STATUS_IO_TIMEOUT;
        }

        Status = i8042ReadDataWait(DeviceExtension, &Value);
        if (!NT_SUCCESS(Status))
        {
            WARN_(I8042PRT, "Failed to read CTRL_SELF_TEST response, status 0x%08lx\n", Status);
            return Status;
        }

        if (Value == KBD_SELF_TEST_OK)
        {
            INFO_(I8042PRT, "CTRL_SELF_TEST completed successfully!\n");
            break;
        }
        else if (Value == KBD_RESEND)
        {
            TRACE_(I8042PRT, "Resending...\n", Value);
            KeStallExecutionProcessor(50);
        }
        else
        {
            WARN_(I8042PRT, "Got 0x%02x instead of 0x55\n", Value);
            return STATUS_IO_DEVICE_ERROR;
        }
    }

    return STATUS_SUCCESS;
}
예제 #18
0
static int
NvramHold(void)
{
    int Error, Timeout = NVDELAY_LIMIT;

    ChipSelOn();
    while (!(*CpuAuxControl & SER_TO_CPU) && Timeout--)
	KeStallExecutionProcessor(NVDELAY_TIME);

    Error = (*CpuAuxControl & SER_TO_CPU) ? ESUCCESS : EIO;

    ChipSelOff();

    return Error;
}
예제 #19
0
VOID
VIOSerialSendCtrlMsg(
    IN WDFDEVICE Device,
    IN ULONG id,
    IN USHORT event,
    IN USHORT value
)
{
    struct VirtIOBufferDescriptor sg;
    struct virtqueue *vq;
    UINT len;
    PPORTS_DEVICE pContext = GetPortsDevice(Device);
    VIRTIO_CONSOLE_CONTROL cpkt;
    int cnt = 0;
    if (!pContext->isHostMultiport)
    {
        return;
    }

    vq = pContext->c_ovq;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s vq = %p\n", __FUNCTION__, vq);

    cpkt.id = id;
    cpkt.event = event;
    cpkt.value = value;

    sg.physAddr = MmGetPhysicalAddress(&cpkt);
    sg.ulSize = sizeof(cpkt);

    WdfSpinLockAcquire(pContext->CVqLock);
    if(0 <= vq->vq_ops->add_buf(vq, &sg, 1, 0, &cpkt, NULL, 0))
    {
        vq->vq_ops->kick(vq);
        while(!vq->vq_ops->get_buf(vq, &len))
        {
           KeStallExecutionProcessor(50);
           if(++cnt > RETRY_THRESHOLD)
           {
              TraceEvents(TRACE_LEVEL_FATAL, DBG_PNP, "<-> %s retries = %d\n", __FUNCTION__, cnt);
              break;
           }
        }
    }
    WdfSpinLockRelease(pContext->CVqLock);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s cnt = %d\n", __FUNCTION__, cnt);
}
예제 #20
0
USHORT GetEEpromSize(
    IN PFDO_DATA FdoData,
    IN PUCHAR CSRBaseIoAddress)
{
    USHORT x, data;
    USHORT size = 1;

    // select EEPROM, reset bits, set EECS
    x = FdoData->ReadPort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG));

    x &= ~(EEDI | EEDO | EESK);
    x |= EECS;
    FdoData->WritePort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG), x);

    // write the read opcode
    ShiftOutBits(FdoData, EEPROM_READ_OPCODE, 3, CSRBaseIoAddress);

    // experiment to discover the size of the eeprom.  request register zero
    // and wait for the eeprom to tell us it has accepted the entire address.
    x = FdoData->ReadPort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG));
    do
    {
        size *= 2;          // each bit of address doubles eeprom size
        x |= EEDO;          // set bit to detect "dummy zero"
        x &= ~EEDI;         // address consists of all zeros

        FdoData->WritePort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG), x);
        KeStallExecutionProcessor(100);
        RaiseClock(FdoData, &x, CSRBaseIoAddress);
        LowerClock(FdoData, &x, CSRBaseIoAddress);

        // check for "dummy zero"
        x = FdoData->ReadPort((PUSHORT)(CSRBaseIoAddress + CSR_EEPROM_CONTROL_REG));
        if (size > EEPROM_MAX_SIZE)
        {
            size = 0;
            break;
        }
    }
    while (x & EEDO);

    // Now read the data (16 bits) in from the selected EEPROM word
    data = ShiftInBits(FdoData, CSRBaseIoAddress);

    EEpromCleanup(FdoData, CSRBaseIoAddress);

    return size;
}
예제 #21
0
BOOLEAN 
mpuDumpBufferNoLock(
  PSOUND_HARDWARE pHw
)
/*++

Routine Description:

    Dumps the contents of the hardware buffer and discard it.
    Assume the hardware is already locked!

Arguments:

    pHw - pointer to the device extension data

Return Value:

    TRUE if we succeed.

--*/
{
  int Count = 0;
  int i;


  // dump the current hardware midi input
  while(Count < 2048) // we should have no more than this
  {
    for(i = 1000; i > 0; i--)
    {
      if (!(INPORT(pHw, MPU_STATUS_PORT) & 0x80)) {  // do we have data waiting (bit 7 clear)?
          INPORT(pHw, MPU_DATA_PORT);  // read and just discard the byte
          Count++;
          break;
      }
      KeStallExecutionProcessor(1);
    }

    // if we waited this long, we don't have anymore data to dump
    if(i == 0)
      break;
  }

  dprintf1(("Hardware buffer dump byte count %x", (ULONG)Count));
  
  return TRUE;  // always
}
예제 #22
0
BOOLEAN
mpuWriteNoLock(
    PSOUND_HARDWARE pHw,
    UCHAR value
)
/*++

Routine Description:

    Write a command or data to the MPU.  The call assumes the
    caller has acquired the spin lock

Arguments:

    pHw - Pointer to the device extension data
    value - the value to be written

Return Value:

    TRUE if written correctly , FALSE otherwise

--*/
{
    int uCount;

    ASSERT(pHw->Key == HARDWARE_KEY);

    uCount = 1000;

    while (uCount--) {
        if (!(INPORT(pHw, MPU_STATUS_PORT) & 0x40)) {  // is it ok to send data (bit 6 clear)? - drude
            OUTPORT(pHw, MPU_DATA_PORT, value);
            break;
        }
        KeStallExecutionProcessor(1); // 1 us
    }

    if (uCount >= 0) {
        return TRUE;
    }

    dprintf1(("mpuWriteNoLock:Failed to write %x to mpu", (ULONG)value));

    return FALSE;
}
예제 #23
0
파일: hardware.c 프로젝트: Moteesh/reactos
static NTSTATUS NTAPI
Send_Byte(PCONTROLLER_INFO ControllerInfo, UCHAR Byte)
/*
 * FUNCTION: Send a byte from the host to the controller's FIFO
 * ARGUMENTS:
 *     ControllerInfo: Info structure for the controller we're writing to
 *     Offset: Offset over the controller's base address that we're writing to
 *     Byte: Byte to write to the bus
 * RETURNS:
 *     STATUS_SUCCESS if the byte was written successfully
 *     STATUS_UNSUCCESSFUL if not
 * NOTES:
 *     - Function designed after flowchart in intel datasheet
 *     - 250us max delay.  Note that this is exactly 5 times longer
 *       than Microsoft recommends stalling the processor
 *     - PAGED_CODE, because we spin for more than the Microsoft-recommended
 *       maximum.
 *     - This function is necessary because sometimes the FIFO reacts slowly
 *       and isn't yet ready to read or write the next byte
 */
{
    int i;

    PAGED_CODE();

    for(i = 0; i < 5; i++)
    {
        if(ReadyForWrite(ControllerInfo))
            break;

        KeStallExecutionProcessor(50);
    }

    if (i < 5)
    {
        WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO, Byte);
        return STATUS_SUCCESS;
    }
    else
    {
        INFO_(FLOPPY, "Send_Byte: timed out trying to write\n");
        HwDumpRegisters(ControllerInfo);
        return STATUS_UNSUCCESSFUL;
    }
}
예제 #24
0
//========================================================================================
// Function:	SB_SMBusPollDone
// Purpose:		This routine wait transmit done.
// Return Value:
//				STATUS_IO_DEVICE_ERROR	- Wait done timeout
//				STATUS_UNSUCCESSFUL		- Transmit error
//				STATUS_PENDING			- Continue
//				STATUS_SUCCESS			- Transmit done
//========================================================================================
static NTSTATUS SB_SMBusPollDone(PTwoWireTransfer pTW)
{
	int WaitDoneCount = 0;

	do
	{
		KeStallExecutionProcessor(30);
		SB_ReadSMBusPort(SMBSTS_ADDR);     
	} while((regSB.SMBSTS.bit.HOSTBUSY != 0) && (WaitDoneCount++ < SB_MAX_TIMEOUT));

	if (WaitDoneCount >= SB_MAX_TIMEOUT)
	{
		pTW->errCode = SUSI_STATUS_TIMEOUT;
		return STATUS_IO_DEVICE_ERROR;
	}

	return SB_SMBusCheckAfterTransmit(pTW);
}
예제 #25
0
파일: hardware.c 프로젝트: Moteesh/reactos
static NTSTATUS NTAPI
Get_Byte(PCONTROLLER_INFO ControllerInfo, PUCHAR Byte)
/*
 * FUNCTION: Read a byte from the controller to the host
 * ARGUMENTS:
 *     ControllerInfo: Info structure for the controller we're reading from
 *     Offset: Offset over the controller's base address  that we're reading from
 *     Byte: Byte to read from the bus
 * RETURNS:
 *     STATUS_SUCCESS if the byte was read successfully
 *     STATUS_UNSUCCESSFUL if not
 * NOTES:
 *     - Function designed after flowchart in intel datasheet
 *     - 250us max delay.  Note that this is exactly 5 times longer
 *       than Microsoft recommends stalling the processor
 *     - Remember that we can be interrupted here, so this might
 *       take much more wall clock time than 250us
 *     - PAGED_CODE because we spin for longer than Microsoft recommends
 */
{
    int i;

    PAGED_CODE();

    for(i = 0; i < 5; i++)
    {
        if(ReadyForRead(ControllerInfo))
            break;

        KeStallExecutionProcessor(50);
    }

    if (i < 5)
    {
        *Byte = READ_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO);
        return STATUS_SUCCESS;
    }
    else
    {
        INFO_(FLOPPY, "Get_Byte: timed out trying to write\n");
        HwDumpRegisters(ControllerInfo);
        return STATUS_UNSUCCESSFUL;
    }
}
예제 #26
0
// Locks all other processors and returns exclusivity pointer. This function
// should never be called before the last exclusivity is released.
_Use_decl_annotations_ EXTERN_C
void *ExclGainExclusivity()
{
    NT_ASSERT(InterlockedAdd(&g_ExclpNumberOfLockedProcessors, 0) == 0);
    _InterlockedAnd(&g_ExclpReleaseAllProcessors, 0);

    const auto numberOfProcessors = KeQueryActiveProcessorCount(nullptr);

    // Allocates DPCs for all processors.
    auto context = reinterpret_cast<ExclusivityContext *>(ExAllocatePoolWithTag(
        NonPagedPoolNx, sizeof(void *) + (numberOfProcessors * sizeof(KDPC)),
        EXCLP_POOL_TAG));
    if (!context)
    {
        return nullptr;
    }

    // Execute a lock DPC for all processors but this.
    context->OldIrql = KeRaiseIrqlToDpcLevel();
    const auto currentCpu = KeGetCurrentProcessorNumber();
    for (auto i = 0ul; i < numberOfProcessors; i++)
    {
        if (i == currentCpu)
        {
            continue;
        }

        // Queue a lock DPC.
        KeInitializeDpc(&context->Dpcs[i], ExclpRaiseIrqlAndWaitDpc, nullptr);
        KeSetTargetProcessorDpc(&context->Dpcs[i], static_cast<CCHAR>(i));
        KeInsertQueueDpc(&context->Dpcs[i], nullptr, nullptr);
    }

    // Wait until all other processors were halted.
    const auto needToBeLocked = numberOfProcessors - 1;
    while (_InterlockedCompareExchange(&g_ExclpNumberOfLockedProcessors,
        needToBeLocked, needToBeLocked) !=
        static_cast<LONG>(needToBeLocked))
    {
        KeStallExecutionProcessor(10);
    }
    return context;
}
예제 #27
0
//========================================================================================
// Function:	SB_SMBusWaitFree
// Purpose:		This routine check flag to wait bus free.
// Return Value:
//				STATUS_IO_DEVICE_ERROR	- Bus busy
//				STATUS_SUCCESS
//========================================================================================
static NTSTATUS SB_SMBusWaitFree(void)
{
	int WaitBusCount = 0;

	SB_ReadSMBusPort(SMBSTS_ADDR);
	while (regSB.SMBSTS.bit.HOSTBUSY && ((WaitBusCount++) < SB_MAX_TIMEOUT))
	{
		KeStallExecutionProcessor(20);
		SB_ReadSMBusPort(SMBSTS_ADDR);
	}

	if (WaitBusCount >= SB_MAX_TIMEOUT)
	{
		DebugPrint(DBG_SMB | DBG_KERNEL, "[SMBus][SB] Wait bus free timeout\n");

		regSB.SMBSTS.reg = 0xFF;
		SB_WriteSMBusPort(SMBSTS_ADDR);
		return STATUS_IO_DEVICE_ERROR;
	}

	return SUSI_STATUS_SUCCESS;
}
예제 #28
0
_Use_decl_annotations_ EXTERN_C
void ExclReleaseExclusivity(
    void *Exclusivity)
{
    if (!Exclusivity)
    {
        return;
    }

    // Tell other processors they can be unlocked with changing the value.
    _InterlockedIncrement(&g_ExclpReleaseAllProcessors);

    // Wait until all other processors were unlocked.
    while (_InterlockedCompareExchange(&g_ExclpNumberOfLockedProcessors, 0, 0))
    {
        KeStallExecutionProcessor(10);
    }

    auto context = static_cast<ExclusivityContext *>(Exclusivity);
    KeLowerIrql(context->OldIrql);
    ExFreePoolWithTag(Exclusivity, EXCLP_POOL_TAG);
}
예제 #29
0
/*
 * FUNCTION: Read data from data port
 */
NTSTATUS
i8042ReadDataWait(
	IN PPORT_DEVICE_EXTENSION DeviceExtension,
	OUT PUCHAR Data)
{
	ULONG Counter;
	NTSTATUS Status;

	Counter = DeviceExtension->Settings.PollingIterations;

	while (Counter--)
	{
		Status = i8042ReadKeyboardData(DeviceExtension, Data);

		if (NT_SUCCESS(Status))
			return Status;

		KeStallExecutionProcessor(50);
	}

	/* Timed out */
	return STATUS_IO_TIMEOUT;
}
예제 #30
0
/*++

Routine Description:

    Detect the presence or absence of a 3812 (adlib-compatible) synthesizer
    at the given i/o address by starting the timer and looking for an
    overflow. Can be used to detect left and right synthesizers separately.

Arguments:

    base - base output address
    inbase - base input address

Return Value:

    TRUE if a synthesizer is present at that address

--*/
BOOL
SoundSynthPresent(PUCHAR base, PUCHAR inbase)
{
#define inport(port)	READ_PORT_UCHAR((PUCHAR)(port))

	UCHAR t1, t2;

	DbgPrintf3(("SoundSynthPresent() - Entry"));

	// check if the chip is present
	SoundMidiSendFM(base, 4, 0x60);             // mask T1 & T2
	SoundMidiSendFM(base, 4, 0x80);             // reset IRQ
	t1 = inport(inbase);               		    // read status register
	SoundMidiSendFM(base, 2, 0xff);             // set timer - 1 latch
	SoundMidiSendFM(base, 4, 0x21);             // unmask & start T1
												
	// this timer should go off in 80 us. It sometimes
	// takes more than 100us, but will always have expired within
	// 200 us if it is ever going to.
	KeStallExecutionProcessor(200);
													
	t2 = inport(inbase);                  	    // read status register

	
	SoundMidiSendFM(base, 4, 0x60);
	SoundMidiSendFM(base, 4, 0x80);

														
	if (!((t1 & 0xE0) == 0) || !((t2 & 0xE0) == 0xC0)) {
	    return(FALSE);
	}
	
	return TRUE;

#undef inport

}