⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 NXP产品LPC23XX的开发板的源文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		DbgPrint("ABORTING UsbCom_Create\n");
        goto done;
    }
    
    irpStack = IoGetCurrentIrpStackLocation (Irp);

    //
    // Create a buffer for the RX data when no reads are outstanding.
    //

    deviceExtension->InterruptReadBuffer = NULL;
    deviceExtension->BufferSize = 0;

    switch (MmQuerySystemSize()) {

        case MmLargeSystem: {

            deviceExtension->BufferSize = 4096;
            deviceExtension->InterruptReadBuffer = ExAllocatePool(
                                                 NonPagedPool,
                                                 deviceExtension->BufferSize
                                                 );

            if (deviceExtension->InterruptReadBuffer) {

                break;

            }

        }

        case MmMediumSystem: {

            deviceExtension->BufferSize = 1024;
            deviceExtension->InterruptReadBuffer = ExAllocatePool(
                                                 NonPagedPool,
                                                 deviceExtension->BufferSize
                                                 );

            if (deviceExtension->InterruptReadBuffer) {

                break;

            }

        }

        case MmSmallSystem: {

            deviceExtension->BufferSize = 128;
            deviceExtension->InterruptReadBuffer = ExAllocatePool(
                                                 NonPagedPool,
                                                 deviceExtension->BufferSize
                                                 );

        }

    }

	//DbgPrint("Interrupt buffer size is %d\n", deviceExtension->BufferSize);

    if (!deviceExtension->InterruptReadBuffer) {
       ExReleaseFastMutex(&deviceExtension->OpenMutex);

        deviceExtension->BufferSize = 0;
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
        Irp->IoStatus.Information = 0;

        SerialDump(
            SERIRPPATH,
            ("SERIAL: Complete Irp: %x\n",Irp)
            );

        InterlockedDecrement(&deviceExtension->OpenCount);
        SerialCompleteRequest(deviceExtension, Irp, IO_NO_INCREMENT);

        return STATUS_INSUFFICIENT_RESOURCES;

    }

    //
    // Ok, it looks like we really are going to open.  Lock down the
    // driver.
    //
//    SerialLockPagableSectionByHandle(SerialGlobals.PAGESER_Handle); henry

    //
    // Power up the stack
    //

//    (void)SerialGotoPowerState(DeviceObject, deviceExtension, PowerDeviceD0); henry

    //
    // Not currently waiting for wake up
    //

    deviceExtension->SendWaitWake = FALSE;

    //
    // On a new open we "flush" the read queue by initializing the
    // count of characters.
    //

    deviceExtension->CharsInInterruptBuffer = 0;
    deviceExtension->LastCharSlot = deviceExtension->InterruptReadBuffer +
                              (deviceExtension->BufferSize - 1);

    deviceExtension->ReadBufferBase = deviceExtension->InterruptReadBuffer;
    deviceExtension->CurrentCharSlot = deviceExtension->InterruptReadBuffer;
    deviceExtension->FirstReadableChar = deviceExtension->InterruptReadBuffer;

    deviceExtension->TotalCharsQueued = 0;

    //
    // We set up the default xon/xoff limits.
    //

    deviceExtension->HandFlow.XoffLimit = deviceExtension->BufferSize >> 3;
    deviceExtension->HandFlow.XonLimit = deviceExtension->BufferSize >> 1;

    deviceExtension->WmiCommData.XoffXmitThreshold = deviceExtension->HandFlow.XoffLimit;
    deviceExtension->WmiCommData.XonXmitThreshold = deviceExtension->HandFlow.XonLimit;

    deviceExtension->BufferSizePt8 = ((3*(deviceExtension->BufferSize>>2))+
                                   (deviceExtension->BufferSize>>4));

	deviceExtension->ToSubmitReadUrb = TRUE;
	deviceExtension->NoReadUrb = FALSE;

    //
    // Mark the device as busy for WMI
    //

    deviceExtension->WmiCommData.IsBusy = TRUE;

    deviceExtension->IrpMaskLocation = NULL;
    deviceExtension->HistoryMask = 0;
    deviceExtension->IsrWaitMask = 0;

    deviceExtension->SendXonChar = FALSE;
    deviceExtension->SendXoffChar = FALSE;


    //
    // The escape char replacement must be reset upon every open.
    //

    deviceExtension->EscapeChar = 0;

done:

	Irp->IoStatus.Status = ntStatus;
    Irp->IoStatus.Information = 0;
	deviceExtension->DeviceIsOpened = TRUE;

    IoCompleteRequest (Irp,
                       IO_NO_INCREMENT
                       );

    UsbCom_DecrementIoCount(DeviceObject);                               

    DbgPrint("exit UsbCom_Create %x\n", ntStatus);


    return ntStatus;
}



LONG
UsbCom_DecrementIoCount(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:

        We keep a pending IO count ( extension->PendingIoCount )  in the device extension.
        The first increment of this count is done on adding the device.
        Subsequently, the count is incremented for each new IRP received and
        decremented when each IRP is completed or passed on.

        Transition to 'one' therefore indicates no IO is pending and signals
        deviceExtension->NoPendingIoEvent. This is needed for processing
        IRP_MN_QUERY_REMOVE_DEVICE

        Transition to 'zero' signals an event ( deviceExtension->RemoveEvent )
        to enable device removal. This is used in processing for IRP_MN_REMOVE_DEVICE
 
Arguments:

        DeviceObject -- ptr to our FDO

Return Value:

        deviceExtension->PendingIoCount


--*/

{
    PDEVICE_EXTENSION deviceExtension;
    LONG ioCount;
    KIRQL             oldIrql;

    deviceExtension = DeviceObject->DeviceExtension;
	KeAcquireSpinLock (&deviceExtension->IoCountSpinLock, &oldIrql);

    ioCount = InterlockedDecrement(&deviceExtension->PendingIoCount);

//    ASSERT(0 <= ioCount);

	if (ioCount > 1)
		KeResetEvent(&deviceExtension->NoPendingIoEvent);

    if (ioCount==1) {
        // trigger no pending io
        KeSetEvent(&deviceExtension->NoPendingIoEvent,
                   1,
                   FALSE);
    }

    if (ioCount==0) {
        // trigger remove-device event
        KeSetEvent(&deviceExtension->RemoveEvent,
                   1,
                   FALSE);
    }
	KeReleaseSpinLock (&deviceExtension->IoCountSpinLock, oldIrql);

//    DbgPrint("Exit UsbCom_DecrementIoCount() Pending io count = %x\n", ioCount);
    return ioCount;
}


VOID
UsbCom_IncrementIoCount(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:

        We keep a pending IO count ( extension->PendingIoCount )  in the device extension.
        The first increment of this count is done on adding the device.
        Subsequently, the count is incremented for each new IRP received and
        decremented when each IRP is completed or passed on.

 
Arguments:

        DeviceObject -- ptr to our FDO

Return Value:

        None


--*/
{
    PDEVICE_EXTENSION deviceExtension;
    KIRQL             oldIrql;

    deviceExtension = DeviceObject->DeviceExtension;

//    DbgPrint("Enter UsbCom_IncrementIoCount() Pending io count = %x\n", deviceExtension->PendingIoCount);

	KeAcquireSpinLock (&deviceExtension->IoCountSpinLock, &oldIrql);

    InterlockedIncrement(&deviceExtension->PendingIoCount);

	KeReleaseSpinLock (&deviceExtension->IoCountSpinLock, oldIrql);

  //  DbgPrint("Exit UsbCom_IncrementIoCount() Pending io count = %x\n", deviceExtension->PendingIoCount);
}

NTSTATUS 
SerialGetRegistryKeyValue (
                          IN HANDLE Handle,
                          IN PWCHAR KeyNameString,
                          IN ULONG KeyNameStringLength,
                          IN OUT PVOID Data,
                          IN OUT PULONG DataLength
                          )
/*++

Routine Description:

    Reads a registry key value from an already opened registry key.
    
Arguments:

    Handle              Handle to the opened registry key
    
    KeyNameString       ANSI string to the desired key

    KeyNameStringLength Length of the KeyNameString

    Data                Buffer to place the key value in

    DataLength          Length of the data buffer

Return Value:

    STATUS_SUCCESS if all works, otherwise status of system call that
    went wrong.

--*/
{
   UNICODE_STRING              keyName;
   ULONG                       length;
   PKEY_VALUE_FULL_INFORMATION fullInfo;

   NTSTATUS                    ntStatus = STATUS_INSUFFICIENT_RESOURCES;

   PAGED_CODE();

   DbgPrint("Enter SerialGetRegistryKeyValue\n");


   RtlInitUnicodeString (&keyName, KeyNameString);

   length = sizeof(KEY_VALUE_FULL_INFORMATION) + KeyNameStringLength
      + *DataLength;
   fullInfo = ExAllocatePool(PagedPool, length); 

   if (fullInfo) {
      ntStatus = ZwQueryValueKey (Handle,
                                  &keyName,
                                  KeyValueFullInformation,
                                  fullInfo,
                                  length,
                                  &length);

      if (NT_SUCCESS(ntStatus)) {
         //
         // If there is enough room in the data buffer, copy the output
         //

         if (*DataLength >= fullInfo->DataLength) {
			*DataLength = fullInfo->DataLength;
            RtlCopyMemory (Data, 
                           ((PUCHAR) fullInfo) + fullInfo->DataOffset, 
                           fullInfo->DataLength);
         }
      }

      ExFreePool(fullInfo);
   }

   return ntStatus;
}

LARGE_INTEGER
SerialGetCharTime(
    IN PDEVICE_EXTENSION Extension
    )

/*++

Routine Description:

    This function will return the number of 100 nanosecond intervals
    there are in one character time (based on the present form
    of flow control.

Arguments:

    Extension - Just what it says.

Return Value:

    100 nanosecond intervals in a character time.

--*/

{

    ULONG dataSize;
    ULONG paritySize;
    ULONG stopSize;
    ULONG charTime;
    ULONG bitTime;
    LARGE_INTEGER tmp;


    if ((Extension->LineControl & SERIAL_DATA_MASK) == SERIAL_5_DATA) {
        dataSize = 5;
    } else if ((Extension->LineControl & SERIAL_DATA_MASK)
                == SERIAL_6_DATA) {
        dataSize = 6;
    } else if ((Extension->LineControl & SERIAL_DATA_MASK)
                == SERIAL_7_DATA) {
        dataSize = 7;
    } else if ((Extension->LineControl & SERIAL_DATA_MASK)
                == SERIAL_8_DATA) {
        dataSize = 8;
    }

    paritySize = 1;
    if ((Extension->LineControl & SERIAL_PARITY_MASK)
            == SERIAL_NONE_PARITY) {

        paritySize = 0;

    }

    if (Extension->LineControl & SERIAL_2_STOP) {

        //
        // Even if it is 1.5, for sanities sake were going
        // to say 2.
        //

        stopSize = 2;

    } else {

        stopSize = 1;

    }

    //
    // First we calculate the number of 100 nanosecond intervals
    // are in a single bit time (Approximately).
    //

    bitTime = (10000000+(Extension->CurrentBaud-1))/Extension->CurrentBaud;
    charTime = bitTime + ((dataSize+paritySize+stopSize)*bitTime);

    tmp.QuadPart = charTime;
    return tmp;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -