📄 readwrite.cpp
字号:
pdx->WriteTransfer.NumberOfMapRegisters);
// Close out this IRP
Irp = pdx->WriteTransfer.pIrp;
Irp->IoStatus.Information=
pdx->WriteTransfer.BytesRequested - pdx->WriteTransfer.BytesRemaining
+ pdx->WriteTransfer.CurrentTransferSize
- READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MRTC);
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
// This one's done. Begin working on the next
StartNextPacket(&pdx->dqReadWrite, pdx->DeviceObject);
UnlockDevice(pdx);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
else {
mcsr = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
// shut off go signal for writes
mcsr &= ~AMCC_BUSMASTERED_WRITE_ENABLE_MASK;
WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
// shut off the hardware ints
intCSR = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR);
// clear the "write 1 clear" bits to avoid problems
intCSR &= AMCC_PRESERVE_INTCSR_MASK;
// shut off ints for writes
intCSR &= ~AMCC_BUSMASTERED_WRITE_INT_ENABLE_MASK;
// clear the write int bit
intCSR |= AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK;
WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
// set the internal state to inactive
pdx->WriteTransfer.TransferInProgress = FALSE;
// Conclude the previous "DMA" Transfer
pdx->WriteTransfer.Adapter->DmaOperations->FlushAdapterBuffers(
pdx->WriteTransfer.Adapter,
pdx->WriteTransfer.Mdl,
pdx->WriteTransfer.MapRegisterBase,
pdx->WriteTransfer.LogicalAddress,
pdx->WriteTransfer.CurrentTransferSize,
TRUE);
pdx->WriteTransfer.Adapter->DmaOperations->FreeMapRegisters(
pdx->WriteTransfer.Adapter,
pdx->WriteTransfer.MapRegisterBase,
pdx->WriteTransfer.NumberOfMapRegisters);
// Close out this IRP
Irp = pdx->WriteTransfer.pIrp;
Irp->IoStatus.Information=
pdx->WriteTransfer.BytesRequested - pdx->WriteTransfer.BytesRemaining
+ pdx->WriteTransfer.CurrentTransferSize
- READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MRTC);
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
// This one's done. Begin working on the next
StartNextPacket(&pdx->dqReadWrite, pdx->DeviceObject);
UnlockDevice(pdx);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
}
KdPrint(("SIWDM - Exiting SheldonTimerRoutine\n"));
}
/*
Function Name:
SheldonIsr
Routine Description:
This function processes interrupts from the PCI Device.
Arguments:
Interrupt - pointer to the Interrupt object
ServiceContext - pointer to the Device Extension
Return Value:
TRUE if we handled the interrupt
FALSE if not our interrupt
*/
BOOLEAN SheldonIsr(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) ServiceContext;
ULONG intCSR;
static int count = 0;
KdPrint(("SIWDM - Entering SheldonIsr\n"));
/////////////////
// IO and memory mapped
/////////////////
if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
// get the int register to determine IRQ cause
intCSR = READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR);
// BUSMASTERED READ
if(pdx->ReadTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK))
{
pdx->int_cause = intCSR;
// clear the interrupt occurance bit
// clear the "write 1 clear" bits to avoid problems
intCSR &= AMCC_PRESERVE_INTCSR_MASK;
// clear the reads int bit
intCSR |= AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK;
WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
// request the DPC
IoRequestDpc(pdx->DeviceObject, pdx->ReadTransfer.pIrp, (PVOID) pdx);
KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Read\n"));
return TRUE;
}
// BUSMASTERED WRITE
if(pdx->WriteTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK))
{
pdx->int_cause = intCSR;
// clear the int occurance bit
// clear the "write 1 clear" bits to avoid problems
intCSR &= AMCC_PRESERVE_INTCSR_MASK;
// clear the write int bit
intCSR |= AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK;
WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
// do the real work in the DPC
IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);
KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Write\n"));
return TRUE;
}
// INT Callback Event
if(intCSR & AMCC_NON_BUSMASTERED_INT_ENABLE_MASK)
{
pdx->int_cause = intCSR;
// dummy read mailbox to clear interrupt on 5920
// For real application, this should be replaced with the action
// that shuts off the interrupt. For example, if the hardware
// deasserts INTA (add on interrupt) by polling the mailbox,
// the mailbox action should be taken here so that INTA is
// deasserted. If INTA is not deasserted here, unpredictable
// result will occur, such as continuous interrupt or lockup.
//WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_IMB4, intCSR);
// clear the "write 1 clear" bits to avoid problems
intCSR &= AMCC_PRESERVE_INTCSR_MASK;
intCSR |= AMCC_NON_BUSMASTERED_INT_ENABLE_MASK;
WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
// do the real work in the DPC
IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);
KdPrint(("SIWDM - Exiting SheldonIsr: Callback Event\n"));
return TRUE;
}
}
else {
// get the int register to determine IRQ cause
intCSR = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR);
// BUSMASTERED READ
if(pdx->ReadTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK))
{
pdx->int_cause = intCSR;
// clear the interrupt occurance bit
// clear the "write 1 clear" bits to avoid problems
intCSR &= AMCC_PRESERVE_INTCSR_MASK;
// clear the reads int bit
intCSR |= AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK;
WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
// request the DPC
IoRequestDpc(pdx->DeviceObject, pdx->ReadTransfer.pIrp, (PVOID) pdx);
KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Read\n"));
return TRUE;
}
// BUSMASTERED WRITE
if(pdx->WriteTransfer.TransferInProgress && (intCSR & AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK))
{
pdx->int_cause = intCSR;
// clear the int occurance bit
// clear the "write 1 clear" bits to avoid problems
intCSR &= AMCC_PRESERVE_INTCSR_MASK;
// clear the write int bit
intCSR |= AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK;
WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
// do the real work in the DPC
IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);
KdPrint(("SIWDM - Exiting SheldonIsr: BusMastered Write\n"));
return TRUE;
}
// INT Callback Event
if(intCSR & AMCC_NON_BUSMASTERED_INT_ENABLE_MASK)
{
pdx->int_cause = intCSR;
// dummy read mailbox to clear interrupt on 5920
// For real application, this should be replaced with the action
// that shuts off the interrupt. For example, if the hardware
// deasserts INTA (add on interrupt) by polling the mailbox,
// the mailbox action should be taken here so that INTA is
// deasserted. If INTA is not deasserted here, unpredictable
// result will occur, such as continuous interrupt or lockup.
//WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_IMB4, intCSR);
// clear the "write 1 clear" bits to avoid problems
intCSR &= AMCC_PRESERVE_INTCSR_MASK;
intCSR |= AMCC_NON_BUSMASTERED_INT_ENABLE_MASK;
WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_INTCSR, intCSR);
// do the real work in the DPC
IoRequestDpc(pdx->DeviceObject, pdx->WriteTransfer.pIrp, (PVOID) pdx);
KdPrint(("SIWDM - Exiting SheldonIsr: Callback Event\n"));
return TRUE;
}
}
KdPrint(("SIWDM - Exiting SheldonIsr\n"));
return FALSE;
}
/*
Function Name:
SheldonDpcForIsr
Routine Description:
This function processes delayed procedure calls for interrupts.
Arguments:
Dpc - pointer to the dpc object
pDeviceObj - pointer to the Device Object
Irp - I/O request being serviced
Context - pointer to the device extension
Return Value:
*/
VOID SheldonDpcForIsr(IN PKDPC Dpc, IN PDEVICE_OBJECT pDeviceObj, \
IN PIRP Irp, IN PVOID Context)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) Context;
ULONG cause;
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
BOOLEAN done = FALSE;
ULONG mcsr;
static int count = 0;
KdPrint(("SIWDM - Entering SheldonDpcForIsr\n"));
// get the int register to determine IRQ cause
cause = pdx->int_cause;
// BUSMASTERED READ
if
(
pdx->ReadTransfer.TransferInProgress
&& (AMCC_BUSMASTERED_READ_INT_OCCURRED_MASK & cause)
)
{
// Stop the TimeOut Timer
KeCancelTimer(&pdx->ReadTransfer.Timer);
// Conclude the previous "DMA" Transfer
pdx->ReadTransfer.Adapter->DmaOperations->FlushAdapterBuffers
(
pdx->ReadTransfer.Adapter,
pdx->ReadTransfer.Mdl,
pdx->ReadTransfer.MapRegisterBase,
pdx->ReadTransfer.LogicalAddress,
pdx->ReadTransfer.CurrentTransferSize,
FALSE
);
// Adjust the bytes remaining to reflect the block just transfered
pdx->ReadTransfer.BytesRemaining -=
pdx->ReadTransfer.CurrentTransferSize;
// Tell the OS that more bytes have been transfered
Irp->IoStatus.Information =
pdx->ReadTransfer.BytesRequested
- pdx->ReadTransfer.BytesRemaining;
// now that the last transfer is wrapped up, let's think about the next
if(pdx->ReadTransfer.BytesRemaining > 0)
{
// advance the address pointer to its new location
pdx->ReadTransfer.LogicalAddress +=
pdx->ReadTransfer.CurrentTransferSize;
KeSynchronizeExecution
(
pdx->InterruptObject,
(PKSYNCHRONIZE_ROUTINE) DoBusMasteredRead,
pdx
);
done = FALSE;
ntStatus = STATUS_PENDING;
}
else
{
// turn off the transfer
pdx->ReadTransfer.TransferInProgress = FALSE;
// disable busmastered reads
/////////////////
// IO and memory mapped
/////////////////
if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
mcsr = READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
// shut off go signal for reads
mcsr &= ~AMCC_BUSMASTERED_READ_ENABLE_MASK;
WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
}
else {
mcsr = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
// shut off go signal for reads
mcsr &= ~AMCC_BUSMASTERED_READ_ENABLE_MASK;
WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
}
done = TRUE;
ntStatus = STATUS_SUCCESS;
pdx->ReadTransfer.Adapter->DmaOperations->FreeMapRegisters
(
pdx->ReadTransfer.Adapter,
pdx->ReadTransfer.MapRegisterBase,
pdx->ReadTransfer.NumberOfMapRegisters
);
}
}
// BUSMASTERED WRITE
if
(
pdx->WriteTransfer.TransferInProgress
&& (AMCC_BUSMASTERED_WRITE_INT_OCCURRED_MASK & cause)
)
{
// Stop the TimeOut Timer
KeCancelTimer(&pdx->WriteTransfer.Timer);
// Conclude the previous "DMA" Transfer
pdx->WriteTransfer.Adapter->DmaOperations->FlushAdapterBuffers
(
pdx->WriteTransfer.Adapter,
pdx->WriteTransfer.Mdl,
pdx->WriteTransfer.MapRegisterBase,
pdx->WriteTransfer.LogicalAddress,
pdx->WriteTransfer.CurrentTransferSize,
TRUE
);
// Adjust the bytes remaining to reflect the block just transfered
pdx->WriteTransfer.BytesRemaining -=
pdx->WriteTransfer.CurrentTransferSize;
// Tell the OS that more bytes have been transfered
Irp->IoStatus.Information =
pdx->WriteTransfer.BytesRequested
- pdx->WriteTransfer.BytesRemaining;
// now that the last transfer is wrapped up, let's think about the next
if(pdx->WriteTransfer.BytesRemaining > 0)
{
// advance the address pointer to its new location
pdx->WriteTransfer.LogicalAddress +=
pdx->WriteTransfer.CurrentTransferSize;
KeSynchronizeExecution
(
pdx->InterruptObject,
(PKSYNCHRONIZE_ROUTINE) DoBusMasteredWrite,
pdx
);
done = FALSE;
ntStatus = STATUS_PENDING;
}
else
{
// stop the transfer
pdx->WriteTransfer.TransferInProgress=FALSE;
/////////////////
// IO and memory mapped
/////////////////
if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
mcsr = READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
// shut off go signal for writes
mcsr &= ~AMCC_BUSMASTERED_WRITE_ENABLE_MASK;
WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
}
else {
mcsr = READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR);
// shut off go signal for writes
mcsr &= ~AMCC_BUSMASTERED_WRITE_ENABLE_MASK;
WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR, mcsr);
}
done = TRUE;
ntStatus = STATUS_SUCCESS;
pdx->WriteTransfer.Adapter->DmaOperations->FreeMapRegisters
(
pdx->WriteTransfer.Adapter,
pdx->WriteTransfer.MapRegisterBase,
pdx->WriteTransfer.NumberOfMapRegisters
);
}
}
// Callback
if(AMCC_NON_BUSMASTERED_INT_ENABLE_MASK & cause)
{
ntStatus = STATUS_SUCCESS;
if(pdx->Callback_Event)
KeSetEvent((PKEVENT) pdx->Callback_Event, 0, FALSE);
done = FALSE;
}
// Close out this IRP
if(done)
{
Irp->IoStatus.Status = ntStatus;
// This one's done. Begin working on the next
StartNextPacket(&pdx->dqReadWrite, pDeviceObj);
UnlockDevice(pdx);
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
}
KdPrint(("SIWDM - Exiting SheldonDpcForIsr (%x)\n", ntStatus));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -