PCMCIA Vpp

I am newbie, writing a window 2000 wdm pcmcia driver. I need to set the
pcmcia card’s Vpp (secondary power source) level to 12 volts. The DDK
documentation introduces the PCMCIA_INTERFACE_STANDARD interface routines
that support Vpp and memory operations.

According to DDK, I will need to create and send an IPR_MJ_PNP request that
specifies a IRP_MN_QUERY_INTERFACE minor function code to obtain the
PCMCIA_INTERFACE_STANDARD. I am not sure where and how I should create this
irp: in the startdevice routine? using IoAllocateIrp?

I would appreciate any suggestions.

Wendy


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Hello,
You can use a code like this in the the driver’s AddDevice entry point:

KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, devExt->PDO, NULL, 0, 0,
&event, &statBlock);

if (!irp) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}

irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
irp->IoStatus.Information = 0;

irpStackPointer = IoGetNextIrpStackLocation(irp);

irpStackPointer->MinorFunction = IRP_MN_QUERY_INTERFACE;

irpStackPointer->Parameters.QueryInterface.InterfaceType =
&GUID_PCMCIA_INTERFACE_STANDARD;

irpStackPointer->Parameters.QueryInterface.Size =
sizeof(PCMCIA_INTERFACE_STANDARD);

irpStackPointer->Parameters.QueryInterface.Version = 1;

irpStackPointer->Parameters.QueryInterface.Interface =
&devExt->Interface;

status = IoCallDriver(devExt->PDO, irp);

if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = statBlock.Status;
}

if (!NT_SUCCESS(status)) {
goto cleanup;
}

return STATUS_SUCCESS;

cleanup:
(cleanup code)
return status;

Thanks
Khalid

-----Original Message-----
From: xxxxx@agere.com [mailto:xxxxx@agere.com]
Sent: Thursday, July 19, 2001 3:56 AM
To: NT Developers Interest List
Subject: [ntdev] PCMCIA Vpp

I am newbie, writing a window 2000 wdm pcmcia driver. I need to set the
pcmcia card’s Vpp (secondary power source) level to 12 volts. The DDK
documentation introduces the PCMCIA_INTERFACE_STANDARD interface
routines
that support Vpp and memory operations.

According to DDK, I will need to create and send an IPR_MJ_PNP request
that
specifies a IRP_MN_QUERY_INTERFACE minor function code to obtain the
PCMCIA_INTERFACE_STANDARD. I am not sure where and how I should create
this
irp: in the startdevice routine? using IoAllocateIrp?

I would appreciate any suggestions.

Wendy


You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

I would add that there are laptops out there which will not provide the 12
volts on VPP, no matter how nicely you ask them. The PCMCIA controllers
themselves are fine; all PCMCIA controllers I have seen provide a byte to
set VPP, with an option for 12V. However, whne you put the voltmeter to
it, you will find that some laptops simply will not send more than 5V over
the line, even if the byte in the controller is set correctly.

So, keep this in mind if tech support issues come in. It’s not just a
problem with noname brands; I recently dealt with a Toshiba laptop with
this problem.

From my experience, therefore, producing a card with a 12V VPP requirement
is a tech support nightmare. I recently came across a Toshiba laptop

At 10:41 AM 7/19/2001 -0700, you wrote:

Hello,
You can use a code like this in the the driver’s AddDevice entry point:

KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, devExt->PDO, NULL, 0, 0,
&event, &statBlock);

if (!irp) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}

irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
irp->IoStatus.Information = 0;

irpStackPointer = IoGetNextIrpStackLocation(irp);

irpStackPointer->MinorFunction = IRP_MN_QUERY_INTERFACE;

irpStackPointer->Parameters.QueryInterface.InterfaceType =
&GUID_PCMCIA_INTERFACE_STANDARD;

irpStackPointer->Parameters.QueryInterface.Size =
sizeof(PCMCIA_INTERFACE_STANDARD);

irpStackPointer->Parameters.QueryInterface.Version = 1;

irpStackPointer->Parameters.QueryInterface.Interface =
&devExt->Interface;

status = IoCallDriver(devExt->PDO, irp);

if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = statBlock.Status;
}

if (!NT_SUCCESS(status)) {
goto cleanup;
}

return STATUS_SUCCESS;

cleanup:
(cleanup code)
return status;

Thanks
Khalid

-----Original Message-----
From: xxxxx@agere.com [mailto:xxxxx@agere.com]
Sent: Thursday, July 19, 2001 3:56 AM
To: NT Developers Interest List
Subject: [ntdev] PCMCIA Vpp

I am newbie, writing a window 2000 wdm pcmcia driver. I need to set the
pcmcia card’s Vpp (secondary power source) level to 12 volts. The DDK
documentation introduces the PCMCIA_INTERFACE_STANDARD interface
routines
that support Vpp and memory operations.

According to DDK, I will need to create and send an IPR_MJ_PNP request
that
specifies a IRP_MN_QUERY_INTERFACE minor function code to obtain the
PCMCIA_INTERFACE_STANDARD. I am not sure where and how I should create
this
irp: in the startdevice routine? using IoAllocateIrp?

I would appreciate any suggestions.

Wendy


You are currently subscribed to ntdev as: xxxxx@microsoft.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: xxxxx@excalibur.co.il
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Thanks for the help.

I have implemented the code in my AddDevice entry point and got the 12V.
However, I lost the 12V after I called the driver from user mode
(CreateFile) and close the handle (CloseHandle). If I try to call the
driver again from user mode, I don’t get the 12V. I also tried to unstall
the driver and install it again, in which case the AddDevice routine is
called again, I did not get the 12V either. The only way to get the 12V
back is to reboot the machine.

Below is the code I used to set vpp in AddDevice routine. Any idea what I
might have done wrong?

Thanks,

Wendy

//**********************************************************
//Pdo was passed to AddDevice by the system

KEVENT event;
NTSTATUS status;
PIRP irp;
PIO_STACK_LOCATION irpStackPointer;
IO_STATUS_BLOCK statBlock;
PCMCIA_INTERFACE_STANDARD *pm_interface;

pm_interface = new (PagedPool) PCMCIA_INTERFACE_STANDARD;

if (!pm_interface)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

// Initiate an event to block on
KeInitializeEvent(&event, NotificationEvent, FALSE);

irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, Pdo, NULL, 0, 0,
&event, &statBlock);

if (!irp) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}

irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
irp->IoStatus.Information = 0;

irpStackPointer = IoGetNextIrpStackLocation(irp);

irpStackPointer->MinorFunction = IRP_MN_QUERY_INTERFACE;

irpStackPointer->Parameters.QueryInterface.InterfaceType =
(LPGUID) &GUID_PCMCIA_INTERFACE_STANDARD;

irpStackPointer->Parameters.QueryInterface.Size =
sizeof(PCMCIA_INTERFACE_STANDARD);

irpStackPointer->Parameters.QueryInterface.Version = 1;

irpStackPointer->Parameters.QueryInterface.Interface =
(PINTERFACE) pm_interface;

// send the request down
status = IoCallDriver(Pdo, irp);

if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = statBlock.Status;
}

if (!NT_SUCCESS(status)) {
goto cleanup;
}

// set Vpp

(*pm_interface -> SetVpp) (pm_interface -> Context, PCMCIA_VPP_12V);

// dereference
(*pm_interface -> InterfaceDereference) (pm_interface -> Context);

cleanup:

delete pm_interface;

pm_interface = NULL;

return status;


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Wendy,

Check your power policy code. I suspect you’re powering the device down
using PoRequestPowerIrp() et. al. in your IRP_MJ_CLOSE dispatch routine
(this is very typical, and for many drivers completely valid).

If that’s the case, a correct approach may be to send this IRP, as you’re
doing, from your IRP_MJ_CREATE dispatch, after powering the device up.
Also, you’ll likely not want to call SetVPP() directly from there in your
IRP_MJ_CREATE dispatch, but rather from the IRP_MJ_POWER handler as your
device is powered up or down (IRP_MN_SET_POWER). Dereference the interface
in your IRP_MJ_CLOSE handler after powering your device down.

As a possible important side note, be aware of the way your code is handling
DO_POWER_PAGABLE and DO_POWER_INRUSH as well - this effects whether
IRP_MN_SET_POWER is called at DISPATCH_LEVEL or PASSIVE_LEVEL (although it’s
not clear to me whether SetVPP has any restrictions on IRQL).

There is possibly another (somewhat simpler) way, but I don’t know whether
the bus driver will fail IRP_MN_QUERY_REMOVE IRPs if you have an outstanding
reference to the interface. I’m guessing not, but that’s just a guess. If
it doesn’t, you can leave all of your code in the AddDevice except the
SetVPP() and Dereference. SetVPP() could then go in the IRP_MN_SET_POWER
handler as described above, but you don’t have to hassle with moving the
other code to the Create/Close handlers.

-Tim

Timothy A. Johns — xxxxx@driverdev.com
Driver Development Corporation — 800.841.0092
Bring Up Your Hardware — Fast. www.driverdev.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of xxxxx@agere.com
Sent: Tuesday, July 24, 2001 4:16 PM
To: NT Developers Interest List
Subject: [ntdev] RE: PCMCIA Vpp

Thanks for the help.

I have implemented the code in my AddDevice entry point and got the 12V.
However, I lost the 12V after I called the driver from user mode
(CreateFile) and close the handle (CloseHandle). If I try to call the
driver again from user mode, I don’t get the 12V. I also tried to unstall
the driver and install it again, in which case the AddDevice routine is
called again, I did not get the 12V either. The only way to get the 12V
back is to reboot the machine.

Below is the code I used to set vpp in AddDevice routine. Any idea what I
might have done wrong?

Thanks,

Wendy

//**********************************************************
//Pdo was passed to AddDevice by the system

KEVENT event;
NTSTATUS status;
PIRP irp;
PIO_STACK_LOCATION irpStackPointer;
IO_STATUS_BLOCK statBlock;
PCMCIA_INTERFACE_STANDARD *pm_interface;

pm_interface = new (PagedPool) PCMCIA_INTERFACE_STANDARD;

if (!pm_interface)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

// Initiate an event to block on
KeInitializeEvent(&event, NotificationEvent, FALSE);

irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, Pdo, NULL, 0, 0,
&event, &statBlock);

if (!irp) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}

irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
irp->IoStatus.Information = 0;

irpStackPointer = IoGetNextIrpStackLocation(irp);

irpStackPointer->MinorFunction = IRP_MN_QUERY_INTERFACE;

irpStackPointer->Parameters.QueryInterface.InterfaceType =
(LPGUID) &GUID_PCMCIA_INTERFACE_STANDARD;

irpStackPointer->Parameters.QueryInterface.Size =
sizeof(PCMCIA_INTERFACE_STANDARD);

irpStackPointer->Parameters.QueryInterface.Version = 1;

irpStackPointer->Parameters.QueryInterface.Interface =
(PINTERFACE) pm_interface;

// send the request down
status = IoCallDriver(Pdo, irp);

if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = statBlock.Status;
}

if (!NT_SUCCESS(status)) {
goto cleanup;
}

// set Vpp

(*pm_interface -> SetVpp) (pm_interface -> Context, PCMCIA_VPP_12V);

// dereference
(*pm_interface -> InterfaceDereference) (pm_interface -> Context);

cleanup:

delete pm_interface;

pm_interface = NULL;

return status;


You are currently subscribed to ntdev as: xxxxx@driverdev.com
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com