IEEE 1394 and SBP-2 - Class driver for none of the above

We are trying to support proprietary SBP-2 hardware (NOT a Disk, CD ROM,
SCSI Printer, nor SCSI Scanner) under Windows 2000. We’re having mixed
success with getting our driver up and running.

With the config ROM set for our desired device type (an ‘Other Device’ or
0x1F) and proprietary command set, we can establish a connection with
Windows 2000. Device discovery seems to be working and our device is
enumerated. The surprise removal applet is being called at the appropriate
times. We essentially see all the activity that the SBP-2 port driver
(sbp2port.sys) should be providing for us: login and logout and abort
requests via the SBP-2 interface. This activity has been traced all the way
to the hardware level of our proprietary SBP-2 device.

We are unable at this time to get our driver to talk to the port driver. We
get our driver to load and run. We can call our driver routines and access
functions. But when that driver tries to communicate with the ‘next driver
down’ (looking for the sbp2port.sys port driver) we are not successful.

Specifically:

IoGetNextIrpStackLocation() returns our next IRP stack, however this next
IRP’s DeviceObject = NULL

As part of our debug work, we temporarily modified the config ROM to
masquerade as a IEEE 1394 printer (device type 02) with SCSI command set
support and used the generic print driver to establish a connection with our
hardware and send data to our device (print notepad document). This was
successful, and activity was also traced all the way to the hardware level
of our proprietary SBP-2 device.

Basic question:

How to setup our driver to enable access the next IRP’s DeviceObject which
is hopefully the sbp2port.sys port driver.

Related issues:

INF file structure / Registry structure to install this class and its
appropriate class driver (specifically the ClassInstall32 Section and
ClassInstall32.Services Section) is a bit unclear to us at this time. Any
suggestions would be helpful.

Our config ROM reports a directory_spec_id and directory_version of 0x609e
to reflect SBP-2 support, and command_set_spec_ID and command_set are set to
reflect our vendor specific nature.

The DDK and MSDN resources such as
http://www.microsoft.com/hwdev/tech/print/sbp2_w2000.asp or
http://www.microsoft.com/hwdev/tech/print/scsiprint.asphave been marginally
helpful, but have not found our situation addressed in enough detail to
finish our work here.

Any suggestions and comments would be greatly appreciated.

Regards,
Peter

xxxxx@nhresearch.com

You get a pointer to the lower device in you AddDevice routine where you
should be attaching your device object onto the stack.

IoCallDriver will fill in the DeviceObject field of the
NextStackLocation for you. Your driver is responsible for filling out
the Parameters part of the next stack location before sending the IRP
down.

-p

-----Original Message-----
From: Peter Barbour [mailto:xxxxx@nhresearch.com]
Sent: Monday, June 24, 2002 2:08 PM
To: NT Developers Interest List
Subject: [ntdev] IEEE 1394 and SBP-2 - Class driver for none of the
above

We are trying to support proprietary SBP-2 hardware (NOT a Disk, CD ROM,
SCSI Printer, nor SCSI Scanner) under Windows 2000. We’re having mixed
success with getting our driver up and running.

With the config ROM set for our desired device type (an ‘Other Device’
or
0x1F) and proprietary command set, we can establish a connection with
Windows 2000. Device discovery seems to be working and our device is
enumerated. The surprise removal applet is being called at the
appropriate times. We essentially see all the activity that the SBP-2
port driver
(sbp2port.sys) should be providing for us: login and logout and abort
requests via the SBP-2 interface. This activity has been traced all the
way to the hardware level of our proprietary SBP-2 device.

We are unable at this time to get our driver to talk to the port driver.
We get our driver to load and run. We can call our driver routines and
access functions. But when that driver tries to communicate with the
‘next driver down’ (looking for the sbp2port.sys port driver) we are not
successful.

Specifically:

IoGetNextIrpStackLocation() returns our next IRP stack, however this
next IRP’s DeviceObject = NULL

As part of our debug work, we temporarily modified the config ROM to
masquerade as a IEEE 1394 printer (device type 02) with SCSI command set
support and used the generic print driver to establish a connection with
our hardware and send data to our device (print notepad document). This
was successful, and activity was also traced all the way to the hardware
level of our proprietary SBP-2 device.

Basic question:

How to setup our driver to enable access the next IRP’s DeviceObject
which is hopefully the sbp2port.sys port driver.

Related issues:

INF file structure / Registry structure to install this class and its
appropriate class driver (specifically the ClassInstall32 Section and
ClassInstall32.Services Section) is a bit unclear to us at this time.
Any suggestions would be helpful.

Our config ROM reports a directory_spec_id and directory_version of
0x609e to reflect SBP-2 support, and command_set_spec_ID and command_set
are set to reflect our vendor specific nature.

The DDK and MSDN resources such as
http://www.microsoft.com/hwdev/tech/print/sbp2_w2000.asp or
http://www.microsoft.com/hwdev/tech/print/scsiprint.asphave been
marginally helpful, but have not found our situation addressed in enough
detail to finish our work here.

Any suggestions and comments would be greatly appreciated.

Regards,
Peter

xxxxx@nhresearch.com


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%

Are you copying the current IRP stack location to the next IRP stack
location before sending the request down the chain? If you issue a
getnextirpstacklocation(), it will be empty. It is your job to
initialize it before you send the request down. You can use
IoCopyCurrentIrpStackToNext()
Jamey

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter Barbour
Sent: Monday, June 24, 2002 2:08 PM
To: NT Developers Interest List
Subject: [ntdev] IEEE 1394 and SBP-2 - Class driver for none of the
above

We are trying to support proprietary SBP-2 hardware (NOT a Disk, CD ROM,
SCSI Printer, nor SCSI Scanner) under Windows 2000. We’re having mixed
success with getting our driver up and running.

With the config ROM set for our desired device type (an ‘Other Device’
or
0x1F) and proprietary command set, we can establish a connection with
Windows 2000. Device discovery seems to be working and our device is
enumerated. The surprise removal applet is being called at the
appropriate
times. We essentially see all the activity that the SBP-2 port driver
(sbp2port.sys) should be providing for us: login and logout and abort
requests via the SBP-2 interface. This activity has been traced all the
way
to the hardware level of our proprietary SBP-2 device.

We are unable at this time to get our driver to talk to the port driver.
We
get our driver to load and run. We can call our driver routines and
access
functions. But when that driver tries to communicate with the ‘next
driver
down’ (looking for the sbp2port.sys port driver) we are not successful.

Specifically:

IoGetNextIrpStackLocation() returns our next IRP stack, however this
next
IRP’s DeviceObject = NULL

As part of our debug work, we temporarily modified the config ROM to
masquerade as a IEEE 1394 printer (device type 02) with SCSI command set
support and used the generic print driver to establish a connection with
our
hardware and send data to our device (print notepad document). This was
successful, and activity was also traced all the way to the hardware
level
of our proprietary SBP-2 device.

Basic question:

How to setup our driver to enable access the next IRP’s DeviceObject
which
is hopefully the sbp2port.sys port driver.

Related issues:

INF file structure / Registry structure to install this class and its
appropriate class driver (specifically the ClassInstall32 Section and
ClassInstall32.Services Section) is a bit unclear to us at this time.
Any
suggestions would be helpful.

Our config ROM reports a directory_spec_id and directory_version of
0x609e
to reflect SBP-2 support, and command_set_spec_ID and command_set are
set to
reflect our vendor specific nature.

The DDK and MSDN resources such as
http://www.microsoft.com/hwdev/tech/print/sbp2_w2000.asp or
http://www.microsoft.com/hwdev/tech/print/scsiprint.asphave been
marginally
helpful, but have not found our situation addressed in enough detail to
finish our work here.

Any suggestions and comments would be greatly appreciated.

Regards,
Peter

xxxxx@nhresearch.com


You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to %%email.unsub%%

Thanks Peter and Jamey for the suggestions so far …

You get a pointer to the lower device in you AddDevice routine where you
should be attaching your device object onto the stack.

Our Code:

NTSTATUS AddDevice(IN DRIVER_OBJECT* pDriverObject, IN PDEVICE_OBJECT pdo)
{
.
.
.
// Link our device object into the stack leading to the PDO
pDeviceExtension->pLowerDeviceObject =
IoAttachDeviceToDeviceStack(pDeviceObject, pdo);
if (!pDeviceExtension->pLowerDeviceObject)
{
KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
status = STATUS_DEVICE_REMOVED;
__leave;
}
.
.
.
I believe we are doing this part successfully as you suggested

IoCallDriver will fill in the DeviceObject field of the
NextStackLocation for you. Your driver is responsible for filling out
the Parameters part of the next stack location before sending the IRP
down.

and

Are you copying the current IRP stack location to the next IRP stack
location before sending the request down the chain? If you issue a
getnextirpstacklocation(), it will be empty. It is your job to
initialize it before you send the request down. You can use
IoCopyCurrentIrpStackToNext()
we do this:

NTSTATUS ForwardAndWait(IN DEVICE_OBJECT* pDeviceObject, IN PIRP Irp)
{
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
PAGED_CODE();
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnRequestComplete,
(PVOID) &event, TRUE, TRUE, TRUE);

DEVICE_EXTENSION* pDeviceExtension =
(DEVICE_EXTENSION*)pDeviceObject->DeviceExtension;
IoCallDriver(pDeviceExtension->pLowerDeviceObject, Irp);
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
return Irp->IoStatus.Status;
}

which seems to match your suggestions. This call returns a nonsensical
error code of 0xbb00000c when we try to send a SCSI_REQUEST_BLOCK to the
next Irp stack. I’m sure it my troubles are due to something simple that I
have not completely understood yet. Any more hints?

Regards,

Peter

what does your completion routine (OnRequestComplete) look like? If it
doesn’t return STATUS_MORE_PROCESSING_REQUIRED then you cannot use the
IRP after you have sent it to the lower driver.

it’s just one possible explanation but it’s the one which jumps out at
me first.

-p

-----Original Message-----
From: Peter Barbour [mailto:xxxxx@nhresearch.com]
Sent: Tuesday, June 25, 2002 11:28 AM
To: NT Developers Interest List
Subject: [ntdev] RE: IEEE 1394 and SBP-2 - Class driver for none of the
above

Thanks Peter and Jamey for the suggestions so far …

You get a pointer to the lower device in you AddDevice routine where
you should be attaching your device object onto the stack.

Our Code:

NTSTATUS AddDevice(IN DRIVER_OBJECT* pDriverObject, IN PDEVICE_OBJECT
pdo) { . . .
// Link our device object into the stack leading to the
PDO
pDeviceExtension->pLowerDeviceObject =
IoAttachDeviceToDeviceStack(pDeviceObject, pdo);
if (!pDeviceExtension->pLowerDeviceObject)
{
KdPrint((DRIVERNAME " -
IoAttachDeviceToDeviceStack failed\n"));
status = STATUS_DEVICE_REMOVED;
__leave;
}
.
.
.
I believe we are doing this part successfully as you suggested

IoCallDriver will fill in the DeviceObject field of the
NextStackLocation for you. Your driver is responsible for filling out
the Parameters part of the next stack location before sending the IRP
down.

and

Are you copying the current IRP stack location to the next IRP stack
location before sending the request down the chain? If you issue a
getnextirpstacklocation(), it will be empty. It is your job to
initialize it before you send the request down. You can use
IoCopyCurrentIrpStackToNext()
we do this:

NTSTATUS ForwardAndWait(IN DEVICE_OBJECT* pDeviceObject, IN PIRP Irp) {
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
PAGED_CODE();
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
OnRequestComplete,
(PVOID) &event, TRUE, TRUE, TRUE);

DEVICE_EXTENSION* pDeviceExtension =
(DEVICE_EXTENSION*)pDeviceObject->DeviceExtension;
IoCallDriver(pDeviceExtension->pLowerDeviceObject, Irp);
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE,
NULL);
return Irp->IoStatus.Status;
}

which seems to match your suggestions. This call returns a nonsensical
error code of 0xbb00000c when we try to send a SCSI_REQUEST_BLOCK to the
next Irp stack. I’m sure it my troubles are due to something simple that
I have not completely understood yet. Any more hints?

Regards,

Peter


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%

NTSTATUS OnRequestComplete(IN DEVICE_OBJECT* pDeviceObject, IN PIRP Irp, IN
PKEVENT pev)
{
KeSetEvent(pev, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}

I think this function is coded as you would expect…

Thanks for your continued suggestions.

Peter

-----Original Message-----

what does your completion routine (OnRequestComplete) look like? If it
doesn’t return STATUS_MORE_PROCESSING_REQUIRED then you cannot use the
IRP after you have sent it to the lower driver.

it’s just one possible explanation but it’s the one which jumps out at
me first.

-p