- Use IoBuildAsynchronousFsdRequest() instead of IoBuildDeviceIoControlRequest()

- Use completion routine for completing that type of requests

svn path=/trunk/; revision=28984
This commit is contained in:
Aleksey Bragin 2007-09-09 18:32:30 +00:00
parent 19dc9c4a64
commit f22e04dc25

View file

@ -107,6 +107,13 @@ ClassIoCompletion(
IN PVOID Context
);
NTSTATUS
STDCALL
ClassCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context);
NTSTATUS
STDCALL
DriverEntry(
@ -1837,7 +1844,7 @@ Return Value:
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
IO_STATUS_BLOCK ioStatus;
ULONG controlType;
ULONG controlType, mjFunction;
PIRP irp;
PIO_STACK_LOCATION irpStack;
KEVENT event;
@ -1845,9 +1852,12 @@ Return Value:
ULONG retryCount = MAXIMUM_RETRIES;
NTSTATUS status;
BOOLEAN retry;
LARGE_INTEGER dummy;
PAGED_CODE();
dummy.QuadPart = 0;
//
// Write length to SRB.
//
@ -1917,12 +1927,13 @@ retry:
controlType = IOCTL_SCSI_EXECUTE_OUT;
Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
mjFunction = IRP_MJ_WRITE;
} else {
controlType = IOCTL_SCSI_EXECUTE_IN;
Srb->SrbFlags = SRB_FLAGS_DATA_IN;
mjFunction = IRP_MJ_READ;
}
} else {
@ -1930,21 +1941,19 @@ retry:
BufferLength = 0;
controlType = IOCTL_SCSI_EXECUTE_NONE;
Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
mjFunction = IRP_MJ_FLUSH_BUFFERS;
}
//
// Build device I/O control request with data transfer.
//
irp = IoBuildDeviceIoControlRequest(controlType,
deviceExtension->PortDeviceObject,
NULL,
0,
BufferAddress,
BufferLength,
TRUE,
&event,
&ioStatus);
irp = IoBuildAsynchronousFsdRequest(
mjFunction,
deviceExtension->DeviceObject,
BufferAddress,
(BufferAddress) ? BufferLength : 0,
&dummy,
&ioStatus);
if (irp == NULL) {
ExFreePool(senseInfoBuffer);
@ -1952,6 +1961,9 @@ retry:
return(STATUS_INSUFFICIENT_RESOURCES);
}
// Set event field
irp->UserEvent = &event;
//
// Disable synchronous transfer for these requests.
//
@ -1971,12 +1983,24 @@ retry:
Srb->ScsiStatus = Srb->SrbStatus = 0;
Srb->NextSrb = 0;
// Set completion routine
IoSetCompletionRoutine(
irp,
ClassCompletionRoutine,
NULL,
TRUE,
TRUE,
TRUE);
//
// Get next stack location.
//
irpStack = IoGetNextIrpStackLocation(irp);
irpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
irpStack->Parameters.DeviceIoControl.IoControlCode = controlType;
//
// Set up SRB for execute scsi request. Save SRB address in next stack
// for the port driver.
@ -3551,11 +3575,12 @@ Return Value:
NTSTATUS status;
ULONG modifiedIoControlCode;
// Class can't handle RESET_DEVICE ioctl
if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_RESET_DEVICE)
{
status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
if (irpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_STORAGE_RESET_DEVICE) {
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
status = STATUS_UNSUCCESSFUL;
goto SetStatusAndReturn;
}
@ -4770,3 +4795,39 @@ Return Value:
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
STDCALL
ClassCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PIO_STATUS_BLOCK IoStatusBlock = Irp->UserIosb;
PKEVENT Event = Irp->UserEvent;
PMDL Mdl;
*IoStatusBlock = Irp->IoStatus;
Irp->UserIosb = NULL;
Irp->UserEvent = NULL;
if(Irp->MdlAddress)
{
Mdl = Irp->MdlAddress;
// if necessary - unlock pages
if ((Mdl->MdlFlags & MDL_PAGES_LOCKED) &&
!(Mdl->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED))
{
MmUnlockPages(Mdl);
}
// free this mdl
IoFreeMdl(Mdl);
}
// free irp and set event to unsignaled state
IoFreeIrp(Irp);
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}