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/class... ============================================================================== --- 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; +}