📄 resource.c
字号:
/*
Copyright(c) 1998,1999 SIC/Hitachi,Ltd.
Module Name:
resource.c
Revision History:
26th May 1999 Released
*/
#include "nsc.h"
#include "Externs.h"
#include "Firregs.h"
/*
*************************************************************************
* MyMemAlloc
*************************************************************************
*
*/
PVOID MyMemAlloc(UINT size, BOOLEAN isDmaBuf)
{
NDIS_STATUS stat;
PVOID memptr;
#ifdef UNDER_CE
// For Windows CE, we allocate our contiguous memory for DMA from
// a block of physical memory reserved in the memory map. See externs.h
// for more details.
ASSERT(isDmaBuf == FALSE);
#endif
if (isDmaBuf){
NDIS_PHYSICAL_ADDRESS maxAddr = NDIS_PHYSICAL_ADDRESS_CONST(0x0fffff, 0);
stat = NdisAllocateMemory( &memptr,
size,
NDIS_MEMORY_CONTIGUOUS|NDIS_MEMORY_NONCACHED,
maxAddr);
}
else {
NDIS_PHYSICAL_ADDRESS noMaxAddr = NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
stat = NdisAllocateMemory( &memptr,
size,
0,
noMaxAddr);
}
if (stat == NDIS_STATUS_SUCCESS){
NdisZeroMemory((PVOID)memptr, size);
}
else {
DBGERR((TEXT("Memory allocation failed")));
memptr = NULL;
}
return memptr;
}
/*
*************************************************************************
* MyMemFree
*************************************************************************
*
*/
VOID MyMemFree(PVOID memptr, UINT size, BOOLEAN isDmaBuf)
{
UINT flags = (isDmaBuf) ? NDIS_MEMORY_CONTIGUOUS|NDIS_MEMORY_NONCACHED : 0;
#ifdef UNDER_CE
ASSERT(isDmaBuf == FALSE);
#endif // UNDER_CE
NdisFreeMemory(memptr, size, flags);
}
/*
*************************************************************************
* NewDevice
*************************************************************************
*
*/
IrDevice *NewDevice()
{
IrDevice *newdev;
DEBUGMSG(ZONE_FIRMODE, (TEXT("NewDevice -->\r\n")));
newdev = MyMemAlloc(sizeof(IrDevice), FALSE);
if (newdev){
InitDevice(newdev);
}
DEBUGMSG(ZONE_FIRMODE, (TEXT("NewDevice <--\r\n")));
return newdev;
}
/*
*************************************************************************
* FreeDevice
*************************************************************************
*
*/
VOID FreeDevice(IrDevice *dev)
{
DEBUGMSG(ZONE_FIRMODE, (TEXT("FreeDevice -->\r\n")));
CloseDevice(dev);
MyMemFree((PVOID)dev, sizeof(IrDevice), FALSE);
DEBUGMSG(ZONE_FIRMODE, (TEXT("FreeDevice <--\r\n")));
}
/*
*************************************************************************
* InitDevice
*************************************************************************
*
* Zero out the device object.
*
* Allocate the device object's spinlock, which will persist while
* the device is opened and closed.
*
*/
VOID InitDevice(IrDevice *thisDev)
{
DEBUGMSG(ZONE_FIRMODE, (TEXT("InitDevice -->\r\n")));
NdisZeroMemory((PVOID)thisDev, sizeof(IrDevice));
NdisInitializeListHead(&thisDev->SendQueue);
NdisAllocateSpinLock(&thisDev->QueueLock);
#ifdef UNDER_CE
// CE - calls NdisMInitializeTimer instead of NdisInitializeTimer. This
// requires the NdisAdapterHandle passed into MiniportInitialize.
// Therefore CE initializes the timer after the call to
// NewDevice in MiniportInitialize.
#else // UNDER_CE
NdisInitializeTimer(&thisDev->TurnaroundTimer,
DelayedWrite,
thisDev);
#endif // !UNDER_CE
NdisInitializeListHead(&thisDev->rcvBufBuf);
NdisInitializeListHead(&thisDev->rcvBufFree);
NdisInitializeListHead(&thisDev->rcvBufFull);
NdisInitializeListHead(&thisDev->rcvBufPend);
DBGWARN((TEXT("NSC FIR Init: Buf:%x Free:%x Full:%x Pend:%x\n"),
&thisDev->rcvBufBuf, &thisDev->rcvBufFree,
&thisDev->rcvBufFull, &thisDev->rcvBufPend));
DEBUGMSG(ZONE_FIRMODE, (TEXT("InitDevice <--\r\n")));
}
/*
*************************************************************************
* OpenDevice
*************************************************************************
*
* Allocate resources for a single device object.
*
* This function should be called with device lock already held.
*
*/
BOOLEAN OpenDevice(IrDevice *thisDev)
{
BOOLEAN result = FALSE;
NDIS_STATUS stat;
UINT bufIndex;
#ifdef UNDER_CE
PVOID pvRcvPkt;
#endif // UNDER_CE
DBGOUT((TEXT("OpenDevice()")));
DEBUGMSG(ZONE_FIRMODE, (TEXT("OpenDevice -->\r\n")));
if (!thisDev){
return FALSE;
}
/*
* Allocate the NDIS packet and NDIS buffer pools
* for this device's RECEIVE buffer queue.
* Our receive packets must only contain one buffer apiece,
* so #buffers == #packets.
*/
NdisAllocatePacketPool(&stat, &thisDev->packetPoolHandle, NUM_RCV_BUFS, 24);
if (stat != NDIS_STATUS_SUCCESS){
goto _openDone;
}
NdisAllocateBufferPool(&stat, &thisDev->bufferPoolHandle, NUM_RCV_BUFS);
if (stat != NDIS_STATUS_SUCCESS){
goto _openDone;
}
#ifdef UNDER_CE
// Windows CE. We get a chunk of memory from our contiguous physical
// buffer. See externs.h for detailed information.
pvRcvPkt = (PUCHAR)g_pvDmaVirtualBase + RCVPACKETS_OFFSET;
#endif // UNDER_CE
/*
* Initialize each of the RECEIVE packet objects for this device.
*/
for (bufIndex = 0; bufIndex < NUM_RCV_BUFS; bufIndex++){
rcvBuffer *rcvBuf = MyMemAlloc(sizeof(rcvBuffer), FALSE);
PVOID buf;
if (!rcvBuf)
{
goto _openDone;
}
rcvBuf->state = STATE_FREE;
rcvBuf->isDmaBuf = FALSE;
/*
* Allocate a data buffer
*
* This buffer gets swapped with the one on comPortInfo
* and must be the same size.
*/
rcvBuf->dataBuf = NULL;
#ifdef UNDER_CE
buf = pvRcvPkt;
pvRcvPkt = (PUCHAR)pvRcvPkt + RCV_BUFFER_SIZE;
#else // UNDER_CE
buf = MyMemAlloc(RCV_BUFFER_SIZE, TRUE);
if (!buf){
goto _openDone;
}
#endif //!UNDER_CE
// We treat the beginning of the buffer as a LIST_ENTRY.
// Normally we would use NDISSynchronizeInsertHeadList, but the
// Interrupt hasn't been registered yet.
InsertHeadList(&thisDev->rcvBufBuf, (PLIST_ENTRY)buf);
/*
* Allocate the NDIS_PACKET.
*/
NdisAllocatePacket(&stat, &rcvBuf->packet, thisDev->packetPoolHandle);
if (stat != NDIS_STATUS_SUCCESS){
goto _openDone;
}
#if 1
/*
* For future convenience, set the MiniportReserved portion of the packet
* to the index of the rcv buffer that contains it.
* This will be used in ReturnPacketHandler.
*/
*(ULONG *)rcvBuf->packet->MiniportReserved = (ULONG)rcvBuf;
#endif
rcvBuf->dataLen = 0;
InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
}
/*
* Set mediaBusy to TRUE initially. That way, we won't
* IndicateStatus to the protocol in the ISR unless the
* protocol has expressed interest by clearing this flag
* via MiniportSetInformation(OID_IRDA_MEDIA_BUSY).
*/
thisDev->mediaBusy = FALSE;
thisDev->haveIndicatedMediaBusy = FALSE;
/*
* Will set speed to 9600 baud initially.
*/
thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];
thisDev->lastPacketAtOldSpeed = NULL;
thisDev->setSpeedAfterCurrentSendPacket = FALSE;
result = TRUE;
_openDone:
if (!result){
/*
* If we're failing, close the device to free up any resources
* that were allocated for it.
*/
CloseDevice(thisDev);
DBGOUT((TEXT("OpenDevice() failed")));
}
else {
DBGOUT((TEXT("OpenDevice() succeeded")));
}
DEBUGMSG(ZONE_FIRMODE, (TEXT("OpenDevice <--\r\n")));
return result;
}
/*
*************************************************************************
* CloseDevice
*************************************************************************
*
* Free the indicated device's resources.
*
*
* Called for shutdown and reset.
* Don't clear ndisAdapterHandle, since we might just be resetting.
* This function should be called with device lock held.
*
*
*/
VOID CloseDevice(IrDevice *thisDev)
{
PLIST_ENTRY ListEntry;
DBGOUT((TEXT("CloseDevice()")));
DEBUGMSG(ZONE_FIRMODE, (TEXT("CloseDevice -->\r\n")));
if (!thisDev){
return;
}
/*
* Free all resources for the RECEIVE buffer queue.
*/
while (!IsListEmpty(&thisDev->rcvBufFree))
{
rcvBuffer *rcvBuf;
ListEntry = RemoveHeadList(&thisDev->rcvBufFree);
rcvBuf = CONTAINING_RECORD(ListEntry,
rcvBuffer,
listEntry);
if (rcvBuf->packet){
NdisFreePacket(rcvBuf->packet);
rcvBuf->packet = NULL;
}
MyMemFree(rcvBuf, sizeof(rcvBuffer), FALSE);
}
while (!IsListEmpty(&thisDev->rcvBufBuf))
{
ListEntry = RemoveHeadList(&thisDev->rcvBufBuf);
#ifdef UNDER_CE
// Windows CE. Don't need to free since it is just a pointer in our
// reserved physical memory.
#else
MyMemFree(ListEntry, RCV_BUFFER_SIZE, TRUE);
#endif // !UNDER_CE
}
/*
* Free the packet and buffer pool handles for this device.
*/
if (thisDev->packetPoolHandle){
NdisFreePacketPool(thisDev->packetPoolHandle);
thisDev->packetPoolHandle = NULL;
}
if (thisDev->bufferPoolHandle){
NdisFreeBufferPool(thisDev->bufferPoolHandle);
thisDev->bufferPoolHandle = NULL;
}
/*
* Free all resources for the SEND buffer queue.
*/
while (ListEntry = MyInterlockedRemoveHeadList(&thisDev->SendQueue, &thisDev->QueueLock)){
PNDIS_PACKET Packet = CONTAINING_RECORD(ListEntry,
NDIS_PACKET,
MiniportReserved);
NdisMSendComplete(thisDev->ndisAdapterHandle, Packet, NDIS_STATUS_FAILURE);
}
thisDev->mediaBusy = FALSE;
thisDev->haveIndicatedMediaBusy = FALSE;
thisDev->linkSpeedInfo = NULL;
DEBUGMSG(ZONE_FIRMODE, (TEXT("CloseDevice <--\r\n")));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -