📄 nsc.c
字号:
if (PacketToComplete != NULL) {
if (thisDev->lastPacketAtOldSpeed == PacketToComplete) {
thisDev->lastPacketAtOldSpeed=NULL;
SpeedChange=TRUE;
DBGERR(("defered set speed\n"));
SetSpeed(thisDev);
}
}
NdisDprReleaseSpinLock(&thisDev->QueueLock);
if (PacketToComplete != NULL) {
ProcessSendQueue(thisDev);
NdisMSendComplete(thisDev->ndisAdapterHandle, PacketToComplete, PacketStatus);
}
//
// send any received packets to irda.sys
//
DeliverFullBuffers(thisDev);
SyncSetInterruptMask(thisDev, TRUE);
LOG("<== MiniportHandleInterrupt");
DBGOUT(("<== MiniportHandleInterrupt"));
}
/*
*************************************************************************
* GetPnPResources
*************************************************************************
*
*
*/
BOOLEAN GetPnPResources(IrDevice *thisDev, NDIS_HANDLE WrapperConfigurationContext)
{
NDIS_STATUS stat;
BOOLEAN result = FALSE;
/*
* We should only need 2 adapter resources (2 IO and 1 interrupt),
* but I've seen devices get extra resources.
* So give the NdisMQueryAdapterResources call room for 10 resources.
*/
#define RESOURCE_LIST_BUF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
UCHAR buf[RESOURCE_LIST_BUF_SIZE];
PNDIS_RESOURCE_LIST resList = (PNDIS_RESOURCE_LIST)buf;
UINT bufSize = RESOURCE_LIST_BUF_SIZE;
NdisMQueryAdapterResources(&stat, WrapperConfigurationContext, resList, &bufSize);
if (stat == NDIS_STATUS_SUCCESS){
PCM_PARTIAL_RESOURCE_DESCRIPTOR resDesc;
BOOLEAN haveIRQ = FALSE,
haveIOAddr = FALSE,
haveDma = FALSE;
UINT i;
for (resDesc = resList->PartialDescriptors, i = 0;
i < resList->Count;
resDesc++, i++){
switch (resDesc->Type){
case CmResourceTypePort:
if (thisDev->CardType==PC87108 &&
(resDesc->u.Port.Start.LowPart==0xEA ||
resDesc->u.Port.Start.LowPart==0x398 ||
resDesc->u.Port.Start.LowPart==0x150))
{
// This is an eval board and this is the config io base address
thisDev->portInfo.ConfigIoBasePhysAddr = resDesc->u.Port.Start.LowPart;
}
else if (thisDev->CardType==PC87308 &&
(resDesc->u.Port.Start.LowPart==0x2E ||
resDesc->u.Port.Start.LowPart==0x15C))
{
// This is an eval board and this is the config io base address
thisDev->portInfo.ConfigIoBasePhysAddr = resDesc->u.Port.Start.LowPart;
}
else if (thisDev->CardType==PC87338 &&
(resDesc->u.Port.Start.LowPart==0x2E ||
resDesc->u.Port.Start.LowPart==0x398 ||
resDesc->u.Port.Start.LowPart==0x15C))
{
// This is an eval board and this is the config io base address
thisDev->portInfo.ConfigIoBasePhysAddr = resDesc->u.Port.Start.LowPart;
}
else
{
if (haveIOAddr){
/*
* The *PNP0510 chip on the IBM ThinkPad 760EL
* gets an extra IO range assigned to it.
* So only pick up the first IO port range;
* ignore this subsequent one.
*/
DBGERR(("Ignoring extra PnP IO base %xh because already using %xh.",
(UINT)resDesc->u.Port.Start.LowPart,
(UINT)thisDev->portInfo.ioBasePhys));
}
else {
thisDev->portInfo.ioBasePhys = resDesc->u.Port.Start.LowPart;
haveIOAddr = TRUE;
DBGOUT(("Got UART IO addr: %xh.", thisDev->portInfo.ioBasePhys));
}
}
break;
case CmResourceTypeInterrupt:
if (haveIRQ){
DBGERR(("Ignoring second PnP IRQ %xh because already using %xh.",
(UINT)resDesc->u.Interrupt.Level, thisDev->portInfo.irq));
}
else {
thisDev->portInfo.irq = resDesc->u.Interrupt.Level;
haveIRQ = TRUE;
DBGOUT(("Got PnP IRQ: %d.", thisDev->portInfo.irq));
}
break;
case CmResourceTypeDma:
if (haveDma){
DBGERR(("Ignoring second DMA address %d because already using %d.",
(UINT)resDesc->u.Dma.Channel, (UINT)thisDev->portInfo.DMAChannel));
}
else {
ASSERT(!(resDesc->u.Dma.Channel&0xffffff00));
thisDev->portInfo.DMAChannel = (UCHAR)resDesc->u.Dma.Channel;
haveDma = TRUE;
DBGOUT(("Got DMA channel: %d.", thisDev->portInfo.DMAChannel));
}
break;
}
}
result = (haveIOAddr && haveIRQ && haveDma);
}
return result;
}
/*
*************************************************************************
* Configure
*************************************************************************
*
* Read configurable parameters out of the system registry.
*
*/
BOOLEAN Configure(
IrDevice *thisDev,
NDIS_HANDLE WrapperConfigurationContext
)
{
//
// Status of Ndis calls.
//
NDIS_STATUS Status;
//
// The handle for reading from the registry.
//
NDIS_HANDLE ConfigHandle;
//
// The value read from the registry.
//
PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
//
// String names of all the parameters that will be read.
//
NDIS_STRING CardTypeStr = CARDTYPE;
NDIS_STRING Dongle_A_TypeStr = DONGLE_A_TYPE;
NDIS_STRING Dongle_B_TypeStr = DONGLE_B_TYPE;
NDIS_STRING MaxConnectRateStr = MAXCONNECTRATE;
UINT Valid_DongleTypes[] = VALID_DONGLETYPES;
DBGOUT(("Configure(0x%x)", thisDev));
NdisOpenConfiguration(&Status, &ConfigHandle, WrapperConfigurationContext);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR(("NdisOpenConfiguration failed in Configure()"));
return FALSE;
}
//
// Read Ir108 Configuration I/O base Address
//
//DbgBreakPoint();
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&CardTypeStr,
NdisParameterHexInteger
);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR(("NdisReadConfiguration failed in accessing CardType."));
NdisCloseConfiguration(ConfigHandle);
return FALSE;
}
thisDev->CardType = (UCHAR)ReturnedValue->ParameterData.IntegerData;
if (!GetPnPResources(thisDev, WrapperConfigurationContext)){
DBGERR(("GetPnPResources failed\n"));
NdisCloseConfiguration(ConfigHandle);
return FALSE;
}
// Read Dongle type constant Number.
//
NdisReadConfiguration(&Status,
&ReturnedValue,
ConfigHandle,
&Dongle_A_TypeStr,
NdisParameterInteger);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR(("NdisReadConfiguration failed in accessing DongleType (0x%x).",Status));
}
thisDev->DonglesSupported = 1;
thisDev->DongleTypes[0] =
(UCHAR)Valid_DongleTypes[(UCHAR)ReturnedValue->ParameterData.IntegerData];
// Read Dongle type constant Number.
//
NdisReadConfiguration(&Status,
&ReturnedValue,
ConfigHandle,
&Dongle_B_TypeStr,
NdisParameterInteger);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR(("NdisReadConfiguration failed in accessing DongleType (0x%x).",
Status));
}
thisDev->DongleTypes[1] = (UCHAR)Valid_DongleTypes[(UCHAR)ReturnedValue->ParameterData.IntegerData];
thisDev->DonglesSupported++;
// Read MaxConnectRate.
//
NdisReadConfiguration(&Status,
&ReturnedValue,
ConfigHandle,
&MaxConnectRateStr,
NdisParameterInteger);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR(("NdisReadConfiguration failed in accessing MaxConnectRate (0x%x).",Status));
thisDev->AllowedSpeedMask = ALL_IRDA_SPEEDS;
}
else
{
thisDev->AllowedSpeedMask = 0;
switch (ReturnedValue->ParameterData.IntegerData)
{
default:
case 4000000:
thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_4M;
case 1152000:
thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_1152K;
case 115200:
thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_115200;
case 57600:
thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_57600;
case 38400:
thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_38400;
case 19200:
thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_19200;
case 9600:
thisDev->AllowedSpeedMask |= NDIS_IRDA_SPEED_9600 | NDIS_IRDA_SPEED_2400;
break;
}
}
NdisCloseConfiguration(ConfigHandle);
DBGOUT(("Configure done: ConfigIO=0x%x UartIO=0x%x irq=%d DMA=%d",
thisDev->portInfo.ConfigIoBaseAddr,thisDev->portInfo.ioBase,
thisDev->portInfo.irq,thisDev->portInfo.DMAChannel));
return TRUE;
}
/*
*************************************************************************
* MiniportInitialize
*************************************************************************
*
*
* Initializes the network interface card.
*
*
*
*/
NDIS_STATUS MiniportInitialize ( PNDIS_STATUS OpenErrorStatus,
PUINT SelectedMediumIndex,
PNDIS_MEDIUM MediumArray,
UINT MediumArraySize,
NDIS_HANDLE NdisAdapterHandle,
NDIS_HANDLE WrapperConfigurationContext
)
{
UINT mediumIndex;
IrDevice *thisDev = NULL;
NDIS_STATUS retStat, result = NDIS_STATUS_SUCCESS;
DBGOUT(("MiniportInitialize()"));
/*
* Search the passed-in array of supported media for the IrDA medium.
*/
for (mediumIndex = 0; mediumIndex < MediumArraySize; mediumIndex++){
if (MediumArray[mediumIndex] == NdisMediumIrda){
break;
}
}
if (mediumIndex < MediumArraySize){
*SelectedMediumIndex = mediumIndex;
}
else {
/*
* Didn't see the IrDA medium
*/
DBGERR(("Didn't see the IRDA medium in MiniportInitialize"));
result = NDIS_STATUS_UNSUPPORTED_MEDIA;
return result;
}
/*
* Allocate a new device object to represent this connection.
*/
thisDev = NewDevice();
if (!thisDev){
return NDIS_STATUS_NOT_ACCEPTED;
}
thisDev->hardwareStatus = NdisHardwareStatusInitializing;
/*
* Allocate resources for this connection.
*/
if (!OpenDevice(thisDev)){
DBGERR(("OpenDevice failed"));
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
/*
* Record the NDIS wrapper's handle for this adapter, which we use
* when we call up to the wrapper.
* (This miniport's adapter handle is just thisDev, the pointer to the device object.).
*/
DBGOUT(("NDIS handle: %xh <-> IRMINI handle: %xh", NdisAdapterHandle, thisDev));
thisDev->ndisAdapterHandle = NdisAdapterHandle;
/*
* Read the system registry to get parameters like COM port number, etc.
*/
if (!Configure(thisDev, WrapperConfigurationContext)){
DBGERR(("Configure failed"));
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
/*
* This call will associate our adapter handle with the wrapper's
* adapter handle. The wrapper will then always use our handle
* when calling us. We use a pointer to the device object as the context.
*/
NdisMSetAttributesEx(NdisAdapterHandle,
(NDIS_HANDLE)thisDev,
0,
NDIS_ATTRIBUTE_DESERIALIZE,
NdisInterfaceInternal);
/*
* Tell NDIS about the range of IO space that we'll be using.
* Puma uses Chip-select mode, so the ConfigIOBase address actually
* follows the regular io, so get both in one shot.
*/
retStat = NdisMRegisterIoPortRange( (PVOID)&thisDev->portInfo.ioBase,
NdisAdapterHandle,
thisDev->portInfo.ioBasePhys,
((thisDev->CardType==PUMA108)?16:8));
if (retStat != NDIS_STATUS_SUCCESS){
DBGERR(("NdisMRegisterIoPortRange failed"));
thisDev->portInfo.ioBase=NULL;
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
if (thisDev->portInfo.ConfigIoBasePhysAddr)
{
/*
* Eval boards require a second IO range.
*
*/
retStat = NdisMRegisterIoPortRange( (PVOID)&thisDev->portInfo.ConfigIoBaseAddr,
NdisAdapterHandle,
thisDev->portInfo.ConfigIoBasePhysAddr,
2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -