|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
initunlo.c
Abstract:
This module contains the code that is very specific to initialization and unload operations in the irenum driver
Author:
Brian Lieuallen, 7-13-2000
Environment:
Kernel mode
Revision History :
--*/
#include "internal.h"
NTSTATUS IrCommAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo )
{ NTSTATUS Status;
WCHAR TempBuffer[256];
PDEVICE_OBJECT Fdo = NULL;
PDEVICE_OBJECT LowerDevice=NULL;
//
// Pointer to the device extension created for this
// device
//
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
D_PNP(DbgPrint("IrComm: AddDevice\n");)
//
// Create the device object for this device.
//
Status = IoCreateDevice( DriverObject, sizeof(FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_NULL, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &Fdo );
if (!NT_SUCCESS(Status)) {
goto CleanUp; }
LowerDevice=IoAttachDeviceToDeviceStack( Fdo, Pdo );
if (LowerDevice == NULL) {
D_ERROR(DbgPrint("IRCOMM: Could not attach to PDO\n");)
Status=STATUS_INSUFFICIENT_RESOURCES;
goto CleanUp; }
Fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE; Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
Fdo->StackSize=LowerDevice->StackSize+1;
DeviceExtension=Fdo->DeviceExtension;
D_ERROR(DbgPrint("IRCOMM: Device Extension %p\n",DeviceExtension);)
DeviceExtension->DeviceObject = Fdo; DeviceExtension->Pdo=Pdo; DeviceExtension->LowerDevice=LowerDevice;
KeInitializeTimer( &DeviceExtension->Read.IntervalTimer );
KeInitializeDpc( &DeviceExtension->Read.IntervalTimerDpc, IntervalTimeProc, DeviceExtension );
KeInitializeTimer( &DeviceExtension->Read.TotalTimer );
KeInitializeDpc( &DeviceExtension->Read.TotalTimerDpc, TotalTimerProc, DeviceExtension );
KeInitializeSpinLock( &DeviceExtension->SpinLock );
KeInitializeSpinLock( &DeviceExtension->Read.ReadLock );
KeInitializeSpinLock( &DeviceExtension->Mask.Lock );
IrCommHandleSymbolicLink( Pdo, &DeviceExtension->InterfaceName, TRUE );
{ IRCOMM_BUS_INFO BusInfo;
QueryPdoInformation( Pdo, IRENUM_CONFIG_SPACE_INFO, &BusInfo, sizeof(BusInfo) );
DeviceExtension->DeviceAddress=BusInfo.DeviceAddress; }
InitializePacketQueue( &DeviceExtension->Write.Queue, DeviceExtension, WriteStartRoutine );
InitializePacketQueue( &DeviceExtension->Read.Queue, DeviceExtension, ReadStartRoutine );
InitializePacketQueue( &DeviceExtension->Mask.Queue, DeviceExtension, MaskStartRoutine );
InitializePacketQueue( &DeviceExtension->Uart.Queue, DeviceExtension, UartStartRoutine );
#if 0
DeviceExtension->LineControl.StopBits=1; DeviceExtension->LineControl.Parity=0; DeviceExtension->LineControl.WordLength=8;
DeviceExtension->BaudRate=115200; #endif
DeviceExtension->Read.BytesInBuffer=0; DeviceExtension->Read.NextFilledByte=&DeviceExtension->Read.InputBuffer[0]; DeviceExtension->Read.NextEmptyByte=&DeviceExtension->Read.InputBuffer[0];
return STATUS_SUCCESS;
CleanUp:
IoDeleteDevice(Fdo);
return Status;
}
NTSTATUS IrCommPnP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status; ULONG i;
switch (irpSp->MinorFunction) {
case IRP_MN_START_DEVICE:
D_PNP(DbgPrint("IRCOMM: IRP_MN_START_DEVICE\n");)
Irp->IoStatus.Status = STATUS_SUCCESS;
return ForwardIrp(DeviceExtension->LowerDevice, Irp);
case IRP_MN_QUERY_STOP_DEVICE:
D_PNP(DbgPrint("IRCOMM: IRP_MN_QUERY_STOP_DEVICE\n");)
Irp->IoStatus.Status = STATUS_SUCCESS;
return ForwardIrp(DeviceExtension->LowerDevice, Irp);
case IRP_MN_CANCEL_STOP_DEVICE:
D_PNP(DbgPrint("IRCOMM: IRP_MN_CANCEL_STOP_DEVICE\n");)
Irp->IoStatus.Status = STATUS_SUCCESS;
return ForwardIrp(DeviceExtension->LowerDevice, Irp);
case IRP_MN_STOP_DEVICE:
D_PNP(DbgPrint("IRCOMM: IRP_MN_STOP_DEVICE\n");)
Irp->IoStatus.Status = STATUS_SUCCESS;
return ForwardIrp(DeviceExtension->LowerDevice, Irp);
case IRP_MN_QUERY_REMOVE_DEVICE:
D_PNP(DbgPrint("IrComm: IRP_MN_QUERY_REMOVE_DEVICE\n");)
Irp->IoStatus.Status = STATUS_SUCCESS;
return ForwardIrp(DeviceExtension->LowerDevice, Irp);
case IRP_MN_CANCEL_REMOVE_DEVICE:
D_PNP(DbgPrint("IrComm: IRP_MN_CANCEL_REMOVE_DEVICE\n");)
Irp->IoStatus.Status = STATUS_SUCCESS;
return ForwardIrp(DeviceExtension->LowerDevice, Irp);
case IRP_MN_SURPRISE_REMOVAL: {
D_PNP(DbgPrint("IrComm: IRP_MN_SURPRISE_REMOVAL\n");)
DeviceExtension->Removing=TRUE;
//
// now that new io is blocked, flush out all pended irps
//
CleanupIoRequests(DeviceExtension);
Irp->IoStatus.Status = STATUS_SUCCESS;
return ForwardIrp(DeviceExtension->LowerDevice, Irp);
} break;
case IRP_MN_REMOVE_DEVICE: {
ULONG NewReferenceCount;
D_PNP(DbgPrint("IrComm: IRP_MN_REMOVE_DEVICE\n");) //
// removing now for sure
//
DeviceExtension->Removing=TRUE; DeviceExtension->Removed=TRUE;
if (DeviceExtension->InterfaceName.Buffer != NULL) {
IrCommHandleSymbolicLink( DeviceExtension->Pdo, &DeviceExtension->InterfaceName, FALSE ); }
IoCopyCurrentIrpStackLocationToNext(Irp);
status=IoCallDriver(DeviceExtension->LowerDevice, Irp);
//
// detach from the driver below
//
IoDetachDevice(DeviceExtension->LowerDevice);
//
// delete our device object
//
IoDeleteDevice(DeviceObject);
D_PNP(DbgPrint("IrComm: IRP_MN_REMOVE_DEVICE exit, %08lx\n",status);)
return status;
}
default: D_PNP(DbgPrint("IrComm: Sending to PDO PnP IRP, MN func=%d\n",irpSp->MinorFunction);)
return ForwardIrp(DeviceExtension->LowerDevice, Irp); }
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS IrCommPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{ PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(DeviceExtension->LowerDevice, Irp);
}
NTSTATUS IrCommWmi( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
|