From: Doron Holan [MS] on
you need to synchronously send the start irp down the stack, you have

> NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
>
> // then pass down this Minor Function for the next driver stack:
> IoSkipCurrentIrpStackLocation(Irp);

you are touching an irp after it left your driver in the call to
IoSkipCurrentStackLocation after calling IoCallDriver. instead, send the
irp and synchronously wait for it to come back. there are many examples in
the DDK which show this.

d
--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"krby_xtrm" <kerby.martino(a)gmail.com> wrote in message
news:1135909598.720708.189900(a)g49g2000cwa.googlegroups.com...
> // This is my complete Pnp Dispatch routine:
> NTSTATUS PciWDMPnp (IN PDEVICE_OBJECT fdo, IN PIRP Irp)
> {
> DbgPrint(DRIVERNAME " - Begin WDM Pnp");
>
> PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
> PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); //
> obtain current IRP
>
> ULONG MinorFunction = IrpStack->MinorFunction;
>
> // sends an IRP to the driver associated with a specified device
> object.
> // pdx->LowerDeviceObject, representing the target device for the
> requested I/O operation.
> NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
>
> // then pass down this Minor Function for the next driver stack:
> IoSkipCurrentIrpStackLocation(Irp);
>
> // added 12-30-05
> PCM_PARTIAL_RESOURCE_LIST raw;
> PCM_PARTIAL_RESOURCE_LIST translated;
>
> switch(MinorFunction)
> {
> case IRP_MN_START_DEVICE:
> // we should check the allocated resource...
> KdPrint((DRIVERNAME " - IRP_MN_START_DEVICE"));
> if (NULL == IrpStack->Parameters.StartDevice.AllocatedResources) ||
> (NULL ==
> IrpStack->Parameters.StartDevice.AllocatedResources.Translated)){
> status = STATUS_INSUFFICIENT_RESOURCES;
> break;
> }
> raw =
> &IrpStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
> translated =
> &IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
> StartDevice(fdo, raw, translated);
> // ~added 12-30-05
> case IRP_MN_REMOVE_DEVICE:
> KdPrint((DRIVERNAME " - IRP_MN_REMOVE_DEVICE"));
> if(pdx->LowerDeviceObject)
> IoDetachDevice(pdx->LowerDeviceObject);
> IoDeleteDevice(fdo); // delete fdo
> break;
> }
> // call the device below us
> IoSkipCurrentIrpStackLocation(Irp);
> return IoCallDriver(pdx->LowerDeviceObject, Irp);
> }
>


From: kerby on
Doron Holan [MS] wrote:
> you need to synchronously send the start irp down the stack, you have
>
>
>>NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
>>
>>// then pass down this Minor Function for the next driver stack:
>>IoSkipCurrentIrpStackLocation(Irp);
>
>
> you are touching an irp after it left your driver in the call to
> IoSkipCurrentStackLocation after calling IoCallDriver. instead, send the
> irp and synchronously wait for it to come back. there are many examples in
> the DDK which show this.
>
> d

one question, is there somehing in my code before that should be removed?

anyway, is what you're saying
something like this:
NTSTATUS PassDownPnP( IN PDEVICE_OBJECT pDO,
IN PIRP pIrp ) {
IoSkipCurrentIrpStackLocation( pIrp );
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDO->DeviceExtension;
return IoCallDriver(pDevExt->pLowerDevice, pIrp);
}

?
-krby_xtrm-
From: Doron Holan [MS] on
i suggest you do alot more reading of the samples, documenation, and
hopefully a book or two. you are missing some fundamental concepts here.

KEVENT startDeviceEvent;
NTSTATUS ntStatus;

//
// We cannot touch the device (send it any non pnp irps) until a
// start device has been passed down to the lower drivers.
// first pass the Irp down
//
KeInitializeEvent(&startDeviceEvent, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
(PVOID)&startDeviceEvent,
TRUE,
TRUE,
TRUE);

ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

if(ntStatus == STATUS_PENDING) {

KeWaitForSingleObject(&startDeviceEvent,
Executive,
KernelMode,
FALSE,
NULL);

ntStatus = Irp->IoStatus.Status;
}

NTSTATUS
IrpCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PKEVENT event = Context;

KeSetEvent(event, 0, FALSE);

return STATUS_MORE_PROCESSING_REQUIRED;
}


--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


"kerby" <kerby(a)driftmark.com> wrote in message
news:uHKbtEUDGHA.3984(a)TK2MSFTNGP14.phx.gbl...
> Doron Holan [MS] wrote:
>> you need to synchronously send the start irp down the stack, you have
>>
>>
>>>NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
>>>
>>>// then pass down this Minor Function for the next driver stack:
>>>IoSkipCurrentIrpStackLocation(Irp);
>>
>>
>> you are touching an irp after it left your driver in the call to
>> IoSkipCurrentStackLocation after calling IoCallDriver. instead, send the
>> irp and synchronously wait for it to come back. there are many examples
>> in the DDK which show this.
>>
>> d
>
> one question, is there somehing in my code before that should be removed?
>
> anyway, is what you're saying
> something like this:
> NTSTATUS PassDownPnP( IN PDEVICE_OBJECT pDO,
> IN PIRP pIrp ) {
> IoSkipCurrentIrpStackLocation( pIrp );
> PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
> pDO->DeviceExtension;
> return IoCallDriver(pDevExt->pLowerDevice, pIrp);
> }
>
> ?
> -krby_xtrm-


From: Calvin Guan on
"synchronously wait for it to come back" means:

1) setup a completion routine for the IRP (which will consume one stack
location, so you can't use IoSkipCurrentIrpStackLocation, use IoCopyXxx
instead), then you forward the request down by IoCallDriver.

2) Your main PNP path will wait on an event allocated from the kernel stack
if the lower driver has not done with the IRP, for instance, it returned
STATUS_PENDING.

3) The lower drivers has done with the IRP eventually, such as the bus
driver has brought the device into a proper state for your device to start.
The lower driver then completes the IRP and the I/O stack unwinding starts.

4) The I/O manage walks the i/o stack all the way back and calls completion
routine installed at each stack location. Your completion routine gets call
then. It will set the event which the main PNP path is waiting on, and
return STATUS_MORE_PROCESSING_REQUIRED so that the stack unwinding (part of
IRP completion process) will stop immediately. This prevents IRP and its
associated resources from being deallocated because the rest of the PNP code
path needs it.

5)Your main PNP path (IRP_MN_START_DEVICE) regains control and go ahead with
whatever needs to be done to init your device.

6) After you are done with the START_DEVICE Irp, do NOT forget to complete
it by calling IoCompleteRequest since the completion process has been paused
by returning SMPR from your completion routine.



If you want to learn how a PNP driver works by writing code from scratch,
you should go over the DDK doc and/or get a good windows driver book such as
Oney's at www.oneysoft.com

If you just want to get your driver going quickly without messing with the
nasty PNP/Po code, you can take the toaster sample from DDK.

HTH, Calvin

--
Calvin Guan (Windows DDK MVP)
NetXtreme Longhorn Miniport Prime
Broadcom Corp. www.broadcom.com

"kerby" <kerby(a)driftmark.com> wrote in message
news:uHKbtEUDGHA.3984(a)TK2MSFTNGP14.phx.gbl...
> Doron Holan [MS] wrote:
>> you need to synchronously send the start irp down the stack, you have
>>
>>
>>>NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
>>>
>>>// then pass down this Minor Function for the next driver stack:
>>>IoSkipCurrentIrpStackLocation(Irp);
>>
>>
>> you are touching an irp after it left your driver in the call to
>> IoSkipCurrentStackLocation after calling IoCallDriver. instead, send the
>> irp and synchronously wait for it to come back. there are many examples
>> in the DDK which show this.
>>
>> d
>
> one question, is there somehing in my code before that should be removed?
>
> anyway, is what you're saying
> something like this:
> NTSTATUS PassDownPnP( IN PDEVICE_OBJECT pDO,
> IN PIRP pIrp ) {
> IoSkipCurrentIrpStackLocation( pIrp );
> PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
> pDO->DeviceExtension;
> return IoCallDriver(pDevExt->pLowerDevice, pIrp);
> }
>
> ?
> -krby_xtrm-


From: Calvin Guan on
> NTSTATUS
> IrpCompletionRoutine(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp,
> IN PVOID Context
> )
> {
> PKEVENT event = Context;
>
> KeSetEvent(event, 0, FALSE);
>
> return STATUS_MORE_PROCESSING_REQUIRED;
> }

Personally, I prefer

if (Irp->PendingReturned) {
KeSetEvent();
}

Not a big deal though.

--
Calvin Guan (Windows DDK MVP)
NetXtreme Longhorn Miniport Prime
Broadcom Corp. www.broadcom.com