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

📄 ioctl.c

📁 如题:POLAR LPC23XX-EK_DEMO software_Keil
💻 C
📖 第 1 页 / 共 5 页
字号:
                Extension->Interrupt,
                SerialGetStats,
                Irp
                );
*/
            SerialGetStats(Irp);

            break;
        }
        case IOCTL_SERIAL_CLEAR_STATS: {
/*
            KeSynchronizeExecution(
                Extension->Interrupt,
                SerialClearStats,
                Extension
                );
*/
			SerialClearStats(deviceExtension);

            break;
        }
        default: {

            ntStatus = STATUS_INVALID_PARAMETER;
            break;
        }
	}

DoneWithIoctl:;

    Irp->IoStatus.Status = ntStatus;

    IoCompleteRequest (Irp,
                       IO_NO_INCREMENT
                       );

    UsbCom_DecrementIoCount(DeviceObject);                       

    return ntStatus;

}

VOID
SerialGetProperties(
    IN PDEVICE_EXTENSION Extension,
    IN PSERIAL_COMMPROP Properties
    )

/*++

Routine Description:

    This function returns the capabilities of this particular
    serial device.

Arguments:

    Extension - The serial device extension.

    Properties - The structure used to return the properties

Return Value:

    None.

--*/

{
	ULONG SupportedBauds = 0;
    RtlZeroMemory(
        Properties,
        sizeof(SERIAL_COMMPROP)
        );

    Properties->PacketLength = sizeof(SERIAL_COMMPROP);
    Properties->PacketVersion = 2;
    Properties->ServiceMask = SERIAL_SP_SERIALCOMM;
    Properties->MaxTxQueue = 0;
    Properties->MaxRxQueue = 0;

    Properties->MaxBaud = SERIAL_BAUD_USER;
    Properties->SettableBaud = Extension->SupportedBauds;

    Properties->ProvSubType = SERIAL_SP_RS232;
    Properties->ProvCapabilities = SERIAL_PCF_DTRDSR |
                                   SERIAL_PCF_RTSCTS |
                                   SERIAL_PCF_CD     |
                                   SERIAL_PCF_PARITY_CHECK |
                                   SERIAL_PCF_XONXOFF |
                                   SERIAL_PCF_SETXCHAR |
                                   SERIAL_PCF_TOTALTIMEOUTS |
                                   SERIAL_PCF_INTTIMEOUTS;
    Properties->SettableParams = SERIAL_SP_PARITY |
                                 SERIAL_SP_BAUD |
                                 SERIAL_SP_DATABITS |
                                 SERIAL_SP_STOPBITS |
                                 SERIAL_SP_HANDSHAKING |
                                 SERIAL_SP_PARITY_CHECK |
                                 SERIAL_SP_CARRIER_DETECT;


    Properties->SettableData = SERIAL_DATABITS_5 |
                               SERIAL_DATABITS_6 |
                               SERIAL_DATABITS_7 |
                               SERIAL_DATABITS_8;
    Properties->SettableStopParity = SERIAL_STOPBITS_10 |
                                     SERIAL_STOPBITS_15 |
                                     SERIAL_STOPBITS_20 |
                                     SERIAL_PARITY_NONE |
                                     SERIAL_PARITY_ODD  |
                                     SERIAL_PARITY_EVEN |
                                     SERIAL_PARITY_MARK |
                                     SERIAL_PARITY_SPACE;
    Properties->CurrentTxQueue = 0;
    Properties->CurrentRxQueue = Extension->BufferSize;

}


NTSTATUS
SerialInternalIoControl(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp)

/*++

Routine Description:

    This routine provides the initial processing for all of the
    internal Ioctrls for the serial device.

Arguments:

    PDevObj - Pointer to the device object for this device

    PIrp - Pointer to the IRP for the current request

Return Value:

    The function value is the final status of the call

--*/

{
    //
    // The status that gets returned to the caller and
    // set in the Irp.
    //
    NTSTATUS status;

    //
    // The current stack location.  This contains all of the
    // information we need to process this particular request.
    //
    PIO_STACK_LOCATION pIrpStack;

    //
    // Just what it says.  This is the serial specific device
    // extension of the device object create for the serial driver.
    //
    PDEVICE_EXTENSION pDevExt = PDevObj->DeviceExtension;

    //
    // A temporary to hold the old IRQL so that it can be
    // restored once we complete/validate this request.
    //
    KIRQL OldIrql;

    NTSTATUS prologueStatus;

    SYSTEM_POWER_STATE cap;

//    SERIAL_LOCKED_PAGED_CODE();
    SerialDump(SERIRPPATH, ("SERIAL: Dispatch InternalIoControl entry for: %x\n", PIrp));

/*
    if ((prologueStatus = SerialIRPPrologue(PIrp, pDevExt))
        != STATUS_SUCCESS) {
       SerialCompleteRequest(pDevExt, PIrp, IO_NO_INCREMENT);
       return prologueStatus;
    }

    SerialDump(SERIRPPATH, ("SERIAL: Dispatch InternalIoControl entry for: %x\n", PIrp));

    if (SerialCompleteIfError(PDevObj, PIrp) != STATUS_SUCCESS) {
        return STATUS_CANCELLED;
    }
*/

    UsbCom_IncrementIoCount(PDevObj);

    // Can't accept a new io request if:
    //  1) device is removed, 
    //  2) has never been started, 
    //  3) is stopped,
    //  4) has a remove request pending,
    //  5) has a stop device pending
    if ( !UsbCom_CanAcceptIoRequests( PDevObj ) ) {
        status = STATUS_DELETE_PENDING;
        PIrp->IoStatus.Status = status;
        PIrp->IoStatus.Information = 0;

        IoCompleteRequest( PIrp, IO_NO_INCREMENT );

		DbgPrint("Removed: %d, Started: %d, Stop: %d\n", 
			pDevExt->DeviceRemoved,
			pDevExt->DeviceStarted,
			pDevExt->StopDeviceRequested);

        UsbCom_DecrementIoCount(PDevObj);                          
        return status;
    }

    pIrpStack = IoGetCurrentIrpStackLocation(PIrp);
    PIrp->IoStatus.Information = 0L;
    status = STATUS_SUCCESS;

    switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode) {

    //
    // Send a wait-wake IRP
    //

    case IOCTL_SERIAL_INTERNAL_DO_WAIT_WAKE:
       //
       // Make sure we can do wait-wake based on what the device reported
       //

       for (cap = PowerSystemSleeping1; cap < PowerSystemMaximum; cap++) {
          if ((pDevExt->DeviceStateMap[cap] >= PowerDeviceD0)
              && (pDevExt->DeviceStateMap[cap] <= pDevExt->DeviceWake)) {
             break;
          }
       }

       if (cap < PowerSystemMaximum) {
          pDevExt->SendWaitWake = TRUE;
          status = STATUS_SUCCESS;
       } else {
          status = STATUS_NOT_SUPPORTED;
       }
       break;

    case IOCTL_SERIAL_INTERNAL_CANCEL_WAIT_WAKE:
       pDevExt->SendWaitWake = FALSE;

       if (pDevExt->PendingWakeIrp != NULL) {
          IoCancelIrp(pDevExt->PendingWakeIrp);
       }

       status = STATUS_SUCCESS;
       break;


    //
    // Put the serial port in a "filter-driver" appropriate state
    //
    // WARNING: This code assumes it is being called by a trusted kernel
    // entity and no checking is done on the validity of the settings
    // passed to IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS
    //
    // If validity checking is desired, the regular ioctl's should be used
    //

    case IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS:
    case IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS: {
       SERIAL_BASIC_SETTINGS basic;
       PSERIAL_BASIC_SETTINGS pBasic;
       SHORT AppropriateDivisor;
       SERIAL_IOCTL_SYNC S;

       if (pIrpStack->Parameters.DeviceIoControl.IoControlCode
           == IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS) {


          //
          // Check the buffer size
          //

          if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength <
              sizeof(SERIAL_BASIC_SETTINGS)) {
             status = STATUS_BUFFER_TOO_SMALL;
             break;
          }

          //
          // Everything is 0 -- timeouts and flow control and fifos.  If
          // We add additional features, this zero memory method
          // may not work.
          //

          RtlZeroMemory(&basic, sizeof(SERIAL_BASIC_SETTINGS));

          basic.TxFifo = 1;
          basic.RxFifo = SERIAL_1_BYTE_HIGH_WATER;

          PIrp->IoStatus.Information = sizeof(SERIAL_BASIC_SETTINGS);
          pBasic = (PSERIAL_BASIC_SETTINGS)PIrp->AssociatedIrp.SystemBuffer;

          //
          // Save off the old settings
          //

          RtlCopyMemory(&pBasic->Timeouts, &pDevExt->Timeouts,
                        sizeof(SERIAL_TIMEOUTS));

          RtlCopyMemory(&pBasic->HandFlow, &pDevExt->HandFlow,
                        sizeof(SERIAL_HANDFLOW));

          pBasic->RxFifo = pDevExt->RxFifoTrigger;
          pBasic->TxFifo = pDevExt->TxFifoAmount;

          //
          // Point to our new settings
          //

          pBasic = &basic;
       } else { // restoring settings
          if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength
              < sizeof(SERIAL_BASIC_SETTINGS)) {
             status = STATUS_BUFFER_TOO_SMALL;
             break;
          }

          pBasic = (PSERIAL_BASIC_SETTINGS)PIrp->AssociatedIrp.SystemBuffer;
       }

       KeAcquireSpinLock(&pDevExt->ControlLock, &OldIrql);

       //
       // Set the timeouts
       //

       RtlCopyMemory(&pDevExt->Timeouts, &pBasic->Timeouts,
                     sizeof(SERIAL_TIMEOUTS));

       //
       // Set flowcontrol
       //

       S.Extension = pDevExt;
       S.Data = &pBasic->HandFlow;
//       KeSynchronizeExecution(pDevExt->Interrupt, SerialSetHandFlow, &S);
//		SerialSetHandFlow(&S); henry
/*
       if (pDevExt->FifoPresent) {
          pDevExt->TxFifoAmount = pBasic->TxFifo;
          pDevExt->RxFifoTrigger = (UCHAR)pBasic->RxFifo;

          WRITE_FIFO_CONTROL(pDevExt->Controller, (UCHAR)0);
          READ_RECEIVE_BUFFER(pDevExt->Controller);
          WRITE_FIFO_CONTROL(pDevExt->Controller,
                             (UCHAR)(SERIAL_FCR_ENABLE | pDevExt->RxFifoTrigger
                                     | SERIAL_FCR_RCVR_RESET
                                     | SERIAL_FCR_TXMT_RESET));
       } else {
          pDevExt->TxFifoAmount = pDevExt->RxFifoTrigger = 0;
          WRITE_FIFO_CONTROL(pDevExt->Controller, (UCHAR)0);
       }
*/

       KeReleaseSpinLock(&pDevExt->ControlLock, OldIrql);


       break;
    }

    default:
       status = STATUS_INVALID_PARAMETER;
       break;

    }

    PIrp->IoStatus.Status = status;

    //SerialDump(SERIRPPATH, ("SERIAL: Complete Irp: %x\n", PIrp));
    SerialCompleteRequest(pDevExt, PIrp, 0);

    return status;
}


NTSTATUS
UsbCom_SetBaud(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp,
	IN ULONG baudrate
	)
{
	NTSTATUS Status;
	USHORT valueBaud;
	UCHAR i,index_matched;


	ULONG baudArray[14] = { 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400,
								110, 300, 1200, 460800, 921600 };
//#ifdef SS_USE_SINGLE_TI
//	USHORT valueBaudArray[14] = { 0xA0, 0xD0, 0x68, 0x34, 0x1A, 0x11, 0x09, 0x04,
//			                    0x68, 0x68, 0x42, 0x68, 0x68 };
//#endif

	USHORT valueBaudArray[14] = { 0x30, 0x18, 0x0C, 0x06, 0x03, 0x02, 0x01, 0x68,
			                    0x68, 0x1A, 0x60, 0x68, 0x68 };

	DbgPrint("enter UsbCom_SetBaud() DO=%08x Irp=%08x BaudRate=%u\n", DeviceObject, Irp, baudrate);

	index_matched = 255;

	for (i=0; i<14; i++)
	{
		if (baudArray[i] == baudrate)
			index_matched = i;
	}

	if (index_matched == 255) {
/*
		Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 
        Irp->IoStatus.Information = 0;

		IoCompleteRequest( Irp,
						   IO_NO_INCREMENT);

		UsbCom_DecrementIoCount(DeviceObject);
*/
		return STATUS_INVALID_PARAMETER;
	}

	valueBaud = valueBaudArray[index_matched];

	Status = UsbCom_SendVendor(DeviceObject, VendorBaudRate, valueBaud);
	
	DbgPrint("exit UsbCom_SetBaud() Status=%08x\n", Status );
	return Status;
}


NTSTATUS
UsbCom_SendVendor(
    IN  PDEVICE_OBJECT DeviceObject,
	IN	UCHAR Request,
	IN	USHORT Value
    )
{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus;
    PURB urb;
    ULONG siz;
    UCHAR ChannelNumber;


    deviceExtension = DeviceObject->DeviceExtension;
    ChannelNumber = (UCHAR)deviceExtension->ChannelNumber;

	Request = ( ((ChannelNumber << 5) & 0xe0) | ( Request & 0x1f ) );

    urb = ExAllocatePool(NonPagedPool,
                         sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));

    if (! urb) {
        DbgPrint("UsbCom_SendVendor()  DO=%08x ExAllocatePool() URB_CONTROL_VENDOR_OR_CLASS_REQUEST : FAIL\n", DeviceObject );
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto UsbCom_SendVendorDone;
	}


	UsbBuildVendorRequest(urb,
                            URB_FUNCTION_VENDOR_DEVICE,
                            (USHORT) sizeof (struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
                            0,		// out direction
                            0,		// reserved bits in request type
                            Request,		// request
                            Value,	// value
                            0,		// index
                            NULL,
							NULL,
							0,
                            NULL);

    DbgPrint("UsbCom_SendVendor() DO=%08x Urb=%08x [Channel=%u Request=%02x Value=%04x]\n", 
		DeviceObject, urb, ChannelNumber, Request, Value);

	ntStatus = UsbCom_CallUSBD(DeviceObject, urb);

    ExF

⌨️ 快捷键说明

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