Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

460 lines
11 KiB

/*
************************************************************************
*
* RESOURCE.c
*
*
* Portions Copyright (C) 1996-2001 National Semiconductor Corp.
* All rights reserved.
* Copyright (C) 1996-2001 Microsoft Corporation. All Rights Reserved.
*
*
*
*************************************************************************
*/
#include "nsc.h"
#include "resource.tmh"
/*
*************************************************************************
* MyMemAlloc
*************************************************************************
*
*/
PVOID NscMemAlloc(UINT size)
{
NDIS_STATUS stat;
PVOID memptr;
stat = NdisAllocateMemoryWithTag(
&memptr,
size,
'rIsN'
);
if (stat == NDIS_STATUS_SUCCESS) {
NdisZeroMemory((PVOID)memptr, size);
} else {
DBGERR(("Memory allocation failed"));
memptr = NULL;
}
return memptr;
}
/*
*************************************************************************
* MyMemFree
*************************************************************************
*
*/
VOID NscMemFree(PVOID memptr)
{
NdisFreeMemory(memptr, 0, 0);
}
PVOID
NscAllocateDmaBuffer(
NDIS_HANDLE AdapterHandle,
ULONG Size,
PNSC_DMA_BUFFER_INFO DmaBufferInfo
)
{
NDIS_STATUS Status;
NdisZeroMemory(DmaBufferInfo,sizeof(*DmaBufferInfo));
DmaBufferInfo->Length=Size;
DmaBufferInfo->AdapterHandle=AdapterHandle;
NdisMAllocateSharedMemory(
DmaBufferInfo->AdapterHandle,
DmaBufferInfo->Length,
TRUE,
&DmaBufferInfo->VirtualAddress,
&DmaBufferInfo->PhysicalAddress
);
if (DmaBufferInfo->VirtualAddress == NULL) {
//
// new style did not work, try old style
//
const NDIS_PHYSICAL_ADDRESS MaxAddress = NDIS_PHYSICAL_ADDRESS_CONST(0x00ffffff, 0);
#if DBG
DbgPrint("NSCIRDA: NdisMAllocateSharedMemoryFailed(), calling NdisAllocateMemory() instead (ok for XP and W2K)\n");
#endif
Status=NdisAllocateMemory(
&DmaBufferInfo->VirtualAddress,
DmaBufferInfo->Length,
NDIS_MEMORY_CONTIGUOUS | NDIS_MEMORY_NONCACHED,
MaxAddress
);
if (Status != STATUS_SUCCESS) {
//
// old style allocation failed
//
NdisZeroMemory(DmaBufferInfo,sizeof(*DmaBufferInfo));
} else {
//
// old style work, not a shared allocation
//
DmaBufferInfo->SharedAllocation=FALSE;
}
} else {
//
// new style worked
//
DmaBufferInfo->SharedAllocation=TRUE;
}
return DmaBufferInfo->VirtualAddress;
}
VOID
NscFreeDmaBuffer(
PNSC_DMA_BUFFER_INFO DmaBufferInfo
)
{
if ((DmaBufferInfo->AdapterHandle == NULL) || (DmaBufferInfo->VirtualAddress == NULL)) {
//
// Not been allocated
//
ASSERT(0);
return;
}
if (DmaBufferInfo->SharedAllocation) {
//
// allocated with ndis shared memory functions
//
NdisMFreeSharedMemory(
DmaBufferInfo->AdapterHandle,
DmaBufferInfo->Length,
TRUE,
DmaBufferInfo->VirtualAddress,
DmaBufferInfo->PhysicalAddress\
);
} else {
//
// Allocated via old api
//
#if DBG
DbgPrint("NSCIRDA: Freeing DMA buffer with NdisFreeMemory() (ok for XP and W2K)\n");
#endif
NdisFreeMemory(
DmaBufferInfo->VirtualAddress,
DmaBufferInfo->Length,
NDIS_MEMORY_CONTIGUOUS | NDIS_MEMORY_NONCACHED
);
}
NdisZeroMemory(DmaBufferInfo,sizeof(*DmaBufferInfo));
return;
}
/*
*************************************************************************
* NewDevice
*************************************************************************
*
*/
IrDevice *NewDevice()
{
IrDevice *newdev;
newdev = NscMemAlloc(sizeof(IrDevice));
if (newdev){
InitDevice(newdev);
}
return newdev;
}
/*
*************************************************************************
* FreeDevice
*************************************************************************
*
*/
VOID FreeDevice(IrDevice *dev)
{
CloseDevice(dev);
NscMemFree((PVOID)dev);
}
/*
*************************************************************************
* 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)
{
NdisZeroMemory((PVOID)thisDev, sizeof(IrDevice));
NdisInitializeListHead(&thisDev->SendQueue);
NdisAllocateSpinLock(&thisDev->QueueLock);
NdisInitializeTimer(&thisDev->TurnaroundTimer,
DelayedWrite,
thisDev);
NdisInitializeListHead(&thisDev->rcvBufBuf);
NdisInitializeListHead(&thisDev->rcvBufFree);
NdisInitializeListHead(&thisDev->rcvBufFull);
NdisInitializeListHead(&thisDev->rcvBufPend);
}
/*
*************************************************************************
* 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;
DBGOUT(("OpenDevice()"));
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, 6 * sizeof(PVOID));
if (stat != NDIS_STATUS_SUCCESS){
goto _openDone;
}
NdisAllocateBufferPool(&stat, &thisDev->bufferPoolHandle, NUM_RCV_BUFS);
if (stat != NDIS_STATUS_SUCCESS){
goto _openDone;
}
//
// allocate the receive buffers used to hold receives SIR frames
//
for (bufIndex = 0; bufIndex < NUM_RCV_BUFS; bufIndex++){
PVOID buf;
buf = NscMemAlloc(RCV_BUFFER_SIZE);
if (!buf){
goto _openDone;
}
// 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);
}
//
// initialize the data structures that keep track of receives buffers
//
for (bufIndex = 0; bufIndex < NUM_RCV_BUFS; bufIndex++){
rcvBuffer *rcvBuf = NscMemAlloc(sizeof(rcvBuffer));
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;
/*
* Allocate the NDIS_PACKET.
*/
NdisAllocatePacket(&stat, &rcvBuf->packet, thisDev->packetPoolHandle);
if (stat != NDIS_STATUS_SUCCESS){
NscMemFree(rcvBuf);
rcvBuf=NULL;
goto _openDone;
}
/*
* 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_PTR *)rcvBuf->packet->MiniportReserved = (ULONG_PTR)rcvBuf;
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 = TRUE;
/*
* 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(("OpenDevice() failed"));
}
else {
DBGOUT(("OpenDevice() succeeded"));
}
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(("CloseDevice()"));
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;
}
NscMemFree(rcvBuf);
}
while (!IsListEmpty(&thisDev->rcvBufBuf))
{
ListEntry = RemoveHeadList(&thisDev->rcvBufBuf);
NscMemFree(ListEntry);
}
/*
* 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;
}
//
// the send queue should be empty now
//
ASSERT(IsListEmpty(&thisDev->SendQueue));
thisDev->mediaBusy = FALSE;
thisDev->haveIndicatedMediaBusy = FALSE;
thisDev->linkSpeedInfo = NULL;
}