www.pudn.com > 9054Src.rar > Dispatch.c
/*******************************************************************************
* Copyright (c) 2006 PLX Technology, Inc.
*
* PLX Technology Inc. licenses this software under specific terms and
* conditions. Use of any of the software or derviatives thereof in any
* product without a PLX Technology chip is strictly prohibited.
*
* PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
* EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. PLX makes no guarantee
* or representations regarding the use of, or the results of the use of,
* the software and documentation in terms of correctness, accuracy,
* reliability, currentness, or otherwise; and you rely on the software,
* documentation and results solely at your own risk.
*
* IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
* LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
* OF ANY KIND. IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
* PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
*
******************************************************************************/
/******************************************************************************
*
* File Name:
*
* Dispatch.c
*
* Description:
*
* This file routes incoming I/O Request packets
*
* Revision History:
*
* 02-01-06 : PCI SDK v4.40
*
******************************************************************************/
#include "ApiFunctions.h"
#include "CommonApi.h"
#include "Dispatch.h"
#include "GlobalVars.h"
#include "PciSupport.h"
#include "PlxIoctl.h"
#include "SupportFunc.h"
#if defined(PLX_WDM_DRIVER)
#include "Driver.h"
#endif
/******************************************************************************
*
* Function : Dispatch_Create
*
* Description: Handle IRP_MJ_CREATE, which allows applications to open handles
* to our device
*
******************************************************************************/
NTSTATUS
Dispatch_Create(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
DebugPrintf_NoInfo(("\n"));
DebugPrintf((
"Received message (IRP=0x%p) ===> IRP_MJ_CREATE\n",
pIrp
));
return PlxCompleteIrpWithInformation(
pIrp,
STATUS_SUCCESS,
0
);
}
/******************************************************************************
*
* Function : Dispatch_Cleanup
*
* Description: Handle the IRP_MJ_CLEANUP IRP
*
******************************************************************************/
NTSTATUS
Dispatch_Cleanup(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
PIO_STACK_LOCATION pStack;
DebugPrintf_NoInfo(("\n"));
DebugPrintf((
"Received message (IRP=0x%p) ===> IRP_MJ_CLEANUP\n",
pIrp
));
pStack =
IoGetCurrentIrpStackLocation(
pIrp
);
// Release any pending notifications owned by proccess
PlxNotificationCancel(
fdo->DeviceExtension,
NULL,
pStack->FileObject
);
// Close DMA channels owned by the process
PlxDmaChannelCleanup(
fdo->DeviceExtension,
pStack->FileObject
);
// Unmap any mappings to PCI BAR spaces owned by process
PlxPciBarSpaceUnmapAll_ByOwner(
fdo->DeviceExtension,
pStack->FileObject
);
// Unmap any mappings to the common buffer owned by process
PlxPciPhysicalMemoryUnmapAll_ByOwner(
fdo->DeviceExtension,
pGbl_CommonBuffer,
pStack->FileObject
);
// Unmap and deallocate any physical memory owned by process
PlxPciPhysicalMemoryFreeAll_ByOwner(
fdo->DeviceExtension,
pStack->FileObject
);
return PlxCompleteIrpWithInformation(
pIrp,
STATUS_SUCCESS,
0
);
}
/******************************************************************************
*
* Function : Dispatch_Close
*
* Description: Handle IRP_MJ_CLOSE, which allows applications to close handles
* to our device
*
******************************************************************************/
NTSTATUS
Dispatch_Close(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
DebugPrintf_NoInfo(("\n"));
DebugPrintf((
"Received message (IRP=0x%p) ===> IRP_MJ_CLOSE\n",
pIrp
));
return PlxCompleteIrpWithInformation(
pIrp,
STATUS_SUCCESS,
0
);
}
#if defined(PLX_WDM_DRIVER)
/******************************************************************************
*
* Function : Dispatch_SystemControl
*
* Description: The dispatch routine for WMI IRPs. It does nothing except
* forward the IRP to the next device in the stack.
*
* Note : This routine is required or DriverVerifier will bug check
*
******************************************************************************/
NTSTATUS
Dispatch_SystemControl(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
DebugPrintf_NoInfo(("\n"));
DebugPrintf((
"Received WMI message (IRP=0x%p) ===> IRP_MJ_SYSTEM_CONTROL\n",
pIrp
));
DebugPrintf(("Forwarded IRP to next lower driver\n"));
IoSkipCurrentIrpStackLocation(
pIrp
);
return IoCallDriver(
((DEVICE_EXTENSION *)fdo->DeviceExtension)->pLowerDeviceObject,
pIrp
);
}
#endif
/******************************************************************************
*
* Function : Dispatch_IoControl
*
* Description: Processes the IOCTL messages sent to this device
*
******************************************************************************/
NTSTATUS
Dispatch_IoControl(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
IOCTLDATA *pIoBuffer;
DEVICE_EXTENSION *pdx;
PIO_STACK_LOCATION pStack;
pdx = fdo->DeviceExtension;
pStack =
IoGetCurrentIrpStackLocation(
pIrp
);
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
pIrp->IoStatus.Information = sizeof(IOCTLDATA);
// Lock device to record usage
PlxLockDevice(
pdx
);
DebugPrintf(("Received PLX message (IRP=0x%p) ===> ", pIrp));
// Handle the PLX specific message
switch (pStack->Parameters.DeviceIoControl.IoControlCode)
{
/***********************************
* PLX device management functions
**********************************/
case PLX_IOCTL_DEVICE_INIT:
DebugPrintf_NoInfo(("PLX_IOCTL_DEVICE_INIT\n"));
// Send the device location data back to the API
pIoBuffer->u.MgmtData.u.Device = pdx->Device;
break;
case PLX_IOCTL_PCI_DEVICE_FIND:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_DEVICE_FIND\n"));
pIoBuffer->ReturnCode =
PlxDeviceFind(
pdx,
&(pIoBuffer->u.MgmtData.u.Device),
(U32*)&(pIoBuffer->u.MgmtData.value)
);
break;
case PLX_IOCTL_DRIVER_VERSION:
DebugPrintf_NoInfo(("PLX_IOCTL_DRIVER_VERSION\n"));
pIoBuffer->u.MgmtData.value =
(PLX_SDK_VERSION_MAJOR << 16) |
(PLX_SDK_VERSION_MINOR << 8) |
(PLX_SDK_VERSION_REVISION << 0);
break;
case PLX_IOCTL_CHIP_TYPE_GET:
DebugPrintf_NoInfo(("PLX_IOCTL_CHIP_TYPE_GET\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode = ApiSuccess;
PlxChipTypeGet(
pdx,
(U32*)&(pIoBuffer->u.MiscData.data[0]),
(U8*)&(pIoBuffer->u.MiscData.data[1])
);
}
break;
case PLX_IOCTL_PCI_BOARD_RESET:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_BOARD_RESET\n"));
if (pdx->PowerState <= MIN_WORKING_POWER_STATE)
{
PlxPciBoardReset(
pdx
);
}
break;
case PLX_IOCTL_PCI_BAR_GET:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_BAR_GET\n"));
pIoBuffer->u.MgmtData.value =
pdx->PciBar[pIoBuffer->u.MgmtData.offset].Physical.QuadPart;
pIoBuffer->u.MgmtData.u.bFlag =
pdx->PciBar[pIoBuffer->u.MgmtData.offset].bIsIoSpace;
break;
case PLX_IOCTL_PCI_BAR_RANGE_GET:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_BAR_RANGE_GET\n"));
pIoBuffer->u.MgmtData.value =
pdx->PciBar[pIoBuffer->u.MgmtData.offset].Size;
break;
case PLX_IOCTL_PCI_BAR_MAP:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_BAR_MAP\n"));
pIoBuffer->ReturnCode =
PlxPciBarMap(
pdx,
(U8)(pIoBuffer->u.MgmtData.offset),
&(pIoBuffer->u.MgmtData.value),
pStack->FileObject
);
break;
case PLX_IOCTL_PCI_BAR_UNMAP:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_BAR_UNMAP\n"));
pIoBuffer->ReturnCode =
PlxPciBarUnmap(
pdx,
PLX_INT_TO_PTR(pIoBuffer->u.MgmtData.value),
pStack->FileObject
);
break;
case PLX_IOCTL_PHYSICAL_MEM_ALLOCATE:
DebugPrintf_NoInfo(("PLX_IOCTL_PHYSICAL_MEM_ALLOCATE\n"));
pIoBuffer->ReturnCode =
PlxPciPhysicalMemoryAllocate(
pdx,
&(pIoBuffer->u.MiscData.u.PciMemory),
(BOOLEAN)(pIoBuffer->u.MiscData.data[0]),
pStack->FileObject
);
break;
case PLX_IOCTL_PHYSICAL_MEM_FREE:
DebugPrintf_NoInfo(("PLX_IOCTL_PHYSICAL_MEM_FREE\n"));
pIoBuffer->ReturnCode =
PlxPciPhysicalMemoryFree(
pdx,
&(pIoBuffer->u.MiscData.u.PciMemory)
);
break;
case PLX_IOCTL_PHYSICAL_MEM_MAP:
DebugPrintf_NoInfo(("PLX_IOCTL_PHYSICAL_MEM_MAP\n"));
pIoBuffer->ReturnCode =
PlxPciPhysicalMemoryMap(
pdx,
&(pIoBuffer->u.MiscData.u.PciMemory),
(BOOLEAN)pIoBuffer->u.MiscData.data[0],
pStack->FileObject
);
break;
case PLX_IOCTL_PHYSICAL_MEM_UNMAP:
DebugPrintf_NoInfo(("PLX_IOCTL_PHYSICAL_MEM_UNMAP\n"));
pIoBuffer->ReturnCode =
PlxPciPhysicalMemoryUnmap(
pdx,
&(pIoBuffer->u.MiscData.u.PciMemory),
pStack->FileObject
);
break;
case PLX_IOCTL_COMMON_BUFFER_PROPERTIES:
DebugPrintf_NoInfo(("PLX_IOCTL_COMMON_BUFFER_PROPERTIES\n"));
// Return buffer information
if (pGbl_CommonBuffer == NULL)
{
pIoBuffer->u.MiscData.u.PciMemory.PhysicalAddr = 0;
pIoBuffer->u.MiscData.u.PciMemory.CpuPhysical = 0;
pIoBuffer->u.MiscData.u.PciMemory.Size = 0;
}
else
{
pIoBuffer->u.MiscData.u.PciMemory.PhysicalAddr =
pGbl_CommonBuffer->BusPhysical;
pIoBuffer->u.MiscData.u.PciMemory.CpuPhysical =
pGbl_CommonBuffer->CpuPhysical;
pIoBuffer->u.MiscData.u.PciMemory.Size =
pGbl_CommonBuffer->Size;
}
break;
/*******************************************
* PCI Register Access Functions
******************************************/
case PLX_IOCTL_PCI_REGISTER_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_REGISTER_READ\n"));
pIoBuffer->u.MgmtData.value =
PlxPciRegisterRead(
pdx,
pIoBuffer->u.MgmtData.u.Device.BusNumber,
pIoBuffer->u.MgmtData.u.Device.SlotNumber,
pIoBuffer->u.MgmtData.offset,
&(pIoBuffer->ReturnCode)
);
DebugPrintf((
"PCI Reg %03X = %08X\n",
pIoBuffer->u.MgmtData.offset,
(U32)pIoBuffer->u.MgmtData.value
));
break;
case PLX_IOCTL_PCI_REGISTER_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_REGISTER_WRITE\n"));
pIoBuffer->ReturnCode =
PlxPciRegisterWrite(
pdx,
pIoBuffer->u.MgmtData.u.Device.BusNumber,
pIoBuffer->u.MgmtData.u.Device.SlotNumber,
pIoBuffer->u.MgmtData.offset,
(U32)pIoBuffer->u.MgmtData.value
);
DebugPrintf((
"Wrote %08X to PCI Reg %03X\n",
(U32)pIoBuffer->u.MgmtData.value,
pIoBuffer->u.MgmtData.offset
));
break;
case PLX_IOCTL_PCI_REG_READ_UNSUPPORTED:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_REG_READ_UNSUPPORTED\n"));
pIoBuffer->u.MgmtData.value =
PlxPciRegisterRead_Unsupported(
pdx,
pIoBuffer->u.MgmtData.u.Device.BusNumber,
pIoBuffer->u.MgmtData.u.Device.SlotNumber,
pIoBuffer->u.MgmtData.offset,
&(pIoBuffer->ReturnCode)
);
break;
case PLX_IOCTL_PCI_REG_WRITE_UNSUPPORTED:
DebugPrintf_NoInfo(("PLX_IOCTL_PCI_REG_WRITE_UNSUPPORTED\n"));
pIoBuffer->ReturnCode =
PlxPciRegisterWrite_Unsupported(
pdx,
pIoBuffer->u.MgmtData.u.Device.BusNumber,
pIoBuffer->u.MgmtData.u.Device.SlotNumber,
pIoBuffer->u.MgmtData.offset,
(U32)pIoBuffer->u.MgmtData.value
);
break;
/***********************************
* Local Register Access Functions
**********************************/
case PLX_IOCTL_REGISTER_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_REGISTER_READ\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
pIoBuffer->u.MgmtData.value = (U32)-1;
}
else
{
pIoBuffer->ReturnCode =
PlxRegisterRead(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32*)&(pIoBuffer->u.MgmtData.value)
);
}
break;
case PLX_IOCTL_REGISTER_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_REGISTER_WRITE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxRegisterWrite(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32)pIoBuffer->u.MgmtData.value
);
}
break;
/********************************
* Interrupt Support Functions
*******************************/
case PLX_IOCTL_INTR_ENABLE:
DebugPrintf_NoInfo(("PLX_IOCTL_INTR_ENABLE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxPciIntrEnable(
pdx,
&(pIoBuffer->u.MiscData.u.IntrInfo)
);
}
break;
case PLX_IOCTL_INTR_DISABLE:
DebugPrintf_NoInfo(("PLX_IOCTL_INTR_DISABLE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxPciIntrDisable(
pdx,
&(pIoBuffer->u.MiscData.u.IntrInfo)
);
}
break;
case PLX_IOCTL_INTR_STATUS_GET:
DebugPrintf_NoInfo(("PLX_IOCTL_INTR_STATUS_GET\n"));
pIoBuffer->ReturnCode =
PlxPciIntrStatusGet(
pdx,
&(pIoBuffer->u.MiscData.u.IntrInfo)
);
break;
case PLX_IOCTL_NOTIFICATION_REGISTER_FOR:
DebugPrintf_NoInfo(("PLX_IOCTL_NOTIFICATION_REGISTER_FOR\n"));
pIoBuffer->ReturnCode =
PlxNotificationRegisterFor(
pdx,
(PLX_INTR*)(pIoBuffer->u.MiscData.data[0]),
(PLX_NOTIFY_OBJECT*)(pIoBuffer->u.MiscData.data[1]),
pStack->FileObject
);
break;
case PLX_IOCTL_NOTIFICATION_WAIT:
DebugPrintf_NoInfo(("PLX_IOCTL_NOTIFICATION_WAIT\n"));
pIoBuffer->ReturnCode =
PlxNotificationWait(
pdx,
(PLX_NOTIFY_OBJECT*)(pIoBuffer->u.MiscData.data[0]),
(U32)pIoBuffer->u.MiscData.data[1]
);
break;
case PLX_IOCTL_NOTIFICATION_CANCEL:
DebugPrintf_NoInfo(("PLX_IOCTL_NOTIFICATION_CANCEL\n"));
pIoBuffer->ReturnCode =
PlxNotificationCancel(
pdx,
(PLX_NOTIFY_OBJECT*)(pIoBuffer->u.MiscData.data[0]),
pStack->FileObject
);
break;
/*********************************
* Bus Memory and I/O Functions
********************************/
case PLX_IOCTL_BUS_IOP_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_BUS_IOP_READ\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxPciBusMemTransfer(
pdx,
pIoBuffer->u.BusIopData.IopSpace,
(U32)pIoBuffer->u.BusIopData.Address,
pIoBuffer->u.BusIopData.bRemap,
PLX_INT_TO_PTR(pIoBuffer->u.BusIopData.Buffer),
pIoBuffer->u.BusIopData.TransferSize,
pIoBuffer->u.BusIopData.AccessType,
TRUE // Specify read operation
);
}
break;
case PLX_IOCTL_BUS_IOP_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_BUS_IOP_WRITE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxPciBusMemTransfer(
pdx,
pIoBuffer->u.BusIopData.IopSpace,
(U32)pIoBuffer->u.BusIopData.Address,
pIoBuffer->u.BusIopData.bRemap,
PLX_INT_TO_PTR(pIoBuffer->u.BusIopData.Buffer),
pIoBuffer->u.BusIopData.TransferSize,
pIoBuffer->u.BusIopData.AccessType,
FALSE // Specify write operation
);
}
break;
case PLX_IOCTL_IO_PORT_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_IO_PORT_READ\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxPciIoPortTransfer(
pIoBuffer->u.BusIopData.Address,
pIoBuffer->u.BusIopData.AccessType,
(VOID*)&(pIoBuffer->u.BusIopData.Buffer),
TRUE // Specify read operation
);
}
break;
case PLX_IOCTL_IO_PORT_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_IO_PORT_WRITE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxPciIoPortTransfer(
pIoBuffer->u.BusIopData.Address,
pIoBuffer->u.BusIopData.AccessType,
(VOID*)&(pIoBuffer->u.BusIopData.Buffer),
FALSE // Specify write operation
);
}
break;
/*******************************
* Power Management Functions
******************************/
case PLX_IOCTL_POWER_LEVEL_SET:
DebugPrintf_NoInfo(("PLX_IOCTL_POWER_LEVEL_SET\n"));
pIoBuffer->ReturnCode =
PlxPciPowerLevelSet(
pdx,
(PLX_POWER_LEVEL)(pIoBuffer->u.MgmtData.value)
);
if (pIoBuffer->ReturnCode == ApiSuccess)
pdx->PowerState = (PLX_POWER_LEVEL)(pIoBuffer->u.MgmtData.value);
break;
case PLX_IOCTL_POWER_LEVEL_GET:
DebugPrintf_NoInfo(("PLX_IOCTL_POWER_LEVEL_GET\n"));
pIoBuffer->ReturnCode =
PlxPciPowerLevelGet(
pdx,
(PLX_POWER_LEVEL*)&(pIoBuffer->u.MgmtData.value)
);
break;
case PLX_IOCTL_PM_NCP_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_PM_NCP_READ\n"));
pIoBuffer->ReturnCode =
PlxPciPmNcpRead(
pdx,
(U8*)&(pIoBuffer->u.MgmtData.value)
);
break;
/***********************************
* Hot Swap Functions
**********************************/
case PLX_IOCTL_HS_NCP_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_HS_NCP_READ\n"));
pIoBuffer->ReturnCode =
PlxPciHotSwapNcpRead(
pdx,
(U8*)&(pIoBuffer->u.MgmtData.value)
);
break;
case PLX_IOCTL_HS_STATUS:
DebugPrintf_NoInfo(("PLX_IOCTL_HS_STATUS\n"));
pIoBuffer->ReturnCode =
PlxPciHotSwapStatus(
pdx,
(U8*)&(pIoBuffer->u.MgmtData.value)
);
break;
/***********************************
* VPD Functions
**********************************/
case PLX_IOCTL_VPD_NCP_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_VPD_NCP_READ\n"));
pIoBuffer->ReturnCode =
PlxPciVpdNcpRead(
pdx,
(U8*)&(pIoBuffer->u.MgmtData.value)
);
break;
case PLX_IOCTL_VPD_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_VPD_READ\n"));
pIoBuffer->ReturnCode =
PlxPciVpdRead(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32*)&(pIoBuffer->u.MgmtData.value)
);
break;
case PLX_IOCTL_VPD_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_VPD_WRITE\n"));
pIoBuffer->ReturnCode =
PlxPciVpdWrite(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32)pIoBuffer->u.MgmtData.value
);
break;
/***********************************
* Serial EEPROM Access Functions
**********************************/
case PLX_IOCTL_EEPROM_PRESENT:
DebugPrintf_NoInfo(("PLX_IOCTL_EEPROM_PRESENT\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxEepromPresent(
pdx,
&(pIoBuffer->u.MgmtData.u.bFlag)
);
}
break;
case PLX_IOCTL_EEPROM_READ_BY_OFFSET:
DebugPrintf_NoInfo(("PLX_IOCTL_EEPROM_READ_BY_OFFSET\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxEepromReadByOffset(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32*)&(pIoBuffer->u.MgmtData.value)
);
}
break;
case PLX_IOCTL_EEPROM_WRITE_BY_OFFSET:
DebugPrintf_NoInfo(("PLX_IOCTL_EEPROM_WRITE_BY_OFFSET\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxEepromWriteByOffset(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32)pIoBuffer->u.MgmtData.value
);
}
break;
/**************************************************
* Mailbox and Doorbell Register Access Functions
**************************************************/
case PLX_IOCTL_MAILBOX_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_MAILBOX_READ\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
pIoBuffer->u.MgmtData.value = (U32)-1;
}
else
{
pIoBuffer->ReturnCode =
PlxRegisterMailboxRead(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32*)&(pIoBuffer->u.MgmtData.value)
);
}
break;
case PLX_IOCTL_MAILBOX_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_MAILBOX_WRITE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxRegisterMailboxWrite(
pdx,
pIoBuffer->u.MgmtData.offset,
(U32)pIoBuffer->u.MgmtData.value
);
}
break;
case PLX_IOCTL_DOORBELL_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_DOORBELL_READ\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
pIoBuffer->u.MgmtData.value = -1;
}
else
{
pIoBuffer->ReturnCode =
PlxRegisterDoorbellRead(
pdx,
(U32*)&(pIoBuffer->u.MgmtData.value)
);
}
break;
case PLX_IOCTL_DOORBELL_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_DOORBELL_WRITE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxRegisterDoorbellWrite(
pdx,
(U32)pIoBuffer->u.MgmtData.value
);
}
break;
/****************************
* Messaging Unit Functions
****************************/
case PLX_IOCTL_MU_INBOUND_PORT_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_MU_INBOUND_PORT_READ\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxMuInboundPortRead(
pdx,
(U32*)&(pIoBuffer->u.MgmtData.value)
);
}
break;
case PLX_IOCTL_MU_INBOUND_PORT_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_MU_INBOUND_PORT_WRITE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxMuInboundPortWrite(
pdx,
(U32)pIoBuffer->u.MgmtData.value
);
}
break;
case PLX_IOCTL_MU_OUTBOUND_PORT_READ:
DebugPrintf_NoInfo(("PLX_IOCTL_MU_OUTBOUND_PORT_READ\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxMuOutboundPortRead(
pdx,
(U32*)&(pIoBuffer->u.MgmtData.value)
);
}
break;
case PLX_IOCTL_MU_OUTBOUND_PORT_WRITE:
DebugPrintf_NoInfo(("PLX_IOCTL_MU_OUTBOUND_PORT_WRITE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxMuOutboundPortWrite(
pdx,
(U32)pIoBuffer->u.MgmtData.value
);
}
break;
/***********************************
* DMA Management Functions
**********************************/
case PLX_IOCTL_DMA_CONTROL:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_CONTROL\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaControl(
pdx,
pIoBuffer->u.DmaData.channel,
pIoBuffer->u.DmaData.u.command
);
}
break;
case PLX_IOCTL_DMA_STATUS:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_STATUS\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaStatus(
pdx,
pIoBuffer->u.DmaData.channel
);
}
break;
/***********************
* Block DMA Functions
***********************/
case PLX_IOCTL_DMA_BLOCK_CHANNEL_OPEN:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_BLOCK_CHANNEL_OPEN\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaBlockChannelOpen(
pdx,
pIoBuffer->u.DmaData.channel,
&(pIoBuffer->u.DmaData.u.desc),
pStack->FileObject
);
}
break;
case PLX_IOCTL_DMA_BLOCK_TRANSFER:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_BLOCK_TRANSFER\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaBlockTransfer(
pdx,
pIoBuffer->u.DmaData.channel,
&(pIoBuffer->u.DmaData.u.TxParams)
);
}
break;
case PLX_IOCTL_DMA_BLOCK_CHANNEL_CLOSE:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_BLOCK_CHANNEL_CLOSE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaBlockChannelClose(
pdx,
pIoBuffer->u.DmaData.channel,
TRUE
);
}
break;
/**********************
* SGL DMA Functions
*********************/
case PLX_IOCTL_DMA_SGL_OPEN:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_SGL_OPEN\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaSglChannelOpen(
pdx,
pIoBuffer->u.DmaData.channel,
&(pIoBuffer->u.DmaData.u.desc),
pStack->FileObject
);
}
break;
case PLX_IOCTL_DMA_SGL_TRANSFER:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_SGL_TRANSFER\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaSglTransfer(
pdx,
pIoBuffer->u.DmaData.channel,
&(pIoBuffer->u.DmaData.u.TxParams)
);
}
break;
case PLX_IOCTL_DMA_SGL_CLOSE:
DebugPrintf_NoInfo(("PLX_IOCTL_DMA_SGL_CLOSE\n"));
if (pdx->PowerState > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode =
PlxDmaSglChannelClose(
pdx,
pIoBuffer->u.DmaData.channel,
TRUE
);
}
break;
/*****************************
* Unsupported Messages
****************************/
default:
DebugPrintf_NoInfo((
"Unsupported PLX_IOCTL_Xxx (0x%08x)\n",
pStack->Parameters.DeviceIoControl.IoControlCode
));
pIoBuffer->ReturnCode = ApiUnsupportedFunction;
break;
}
PlxUnlockDevice(
pdx
);
return PlxCompleteIrp(
pIrp,
STATUS_SUCCESS
);
}