Author: fireball
Date: Sun Sep 9 22:32:30 2007
New Revision: 28984
URL:
http://svn.reactos.org/svn/reactos?rev=28984&view=rev
Log:
- Use IoBuildAsynchronousFsdRequest() instead of IoBuildDeviceIoControlRequest()
- Use completion routine for completing that type of requests
Modified:
trunk/reactos/drivers/storage/class/class2/class2.c
Modified: trunk/reactos/drivers/storage/class/class2/class2.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/class/clas…
==============================================================================
--- trunk/reactos/drivers/storage/class/class2/class2.c (original)
+++ trunk/reactos/drivers/storage/class/class2/class2.c Sun Sep 9 22:32:30 2007
@@ -106,6 +106,13 @@
IN PIRP Irp,
IN PVOID Context
);
+
+NTSTATUS
+STDCALL
+ClassCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context);
+
NTSTATUS
STDCALL
@@ -1837,7 +1844,7 @@
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
IO_STATUS_BLOCK ioStatus;
- ULONG controlType;
+ ULONG controlType, mjFunction;
PIRP irp;
PIO_STACK_LOCATION irpStack;
KEVENT event;
@@ -1845,8 +1852,11 @@
ULONG retryCount = MAXIMUM_RETRIES;
NTSTATUS status;
BOOLEAN retry;
+ LARGE_INTEGER dummy;
PAGED_CODE();
+
+ dummy.QuadPart = 0;
//
// Write length to SRB.
@@ -1917,12 +1927,13 @@
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 @@
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 @@
return(STATUS_INSUFFICIENT_RESOURCES);
}
+ // Set event field
+ irp->UserEvent = &event;
+
//
// Disable synchronous transfer for these requests.
//
@@ -1971,11 +1983,23 @@
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
@@ -3551,11 +3575,12 @@
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 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;
+}