Author: fireball
Date: Sat Nov 29 10:24:29 2008
New Revision: 37732
URL:
http://svn.reactos.org/svn/reactos?rev=37732&view=rev
Log:
- Implement ScsiPortCompleteRequest based on OSR description.
See issue #3025 for more details.
Modified:
trunk/reactos/drivers/storage/scsiport/scsiport.c
Modified: trunk/reactos/drivers/storage/scsiport/scsiport.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/scsiport/s…
==============================================================================
--- trunk/reactos/drivers/storage/scsiport/scsiport.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/storage/scsiport/scsiport.c [iso-8859-1] Sat Nov 29 10:24:29
2008
@@ -294,19 +294,114 @@
DbgPrint(Buffer);
}
+/* An internal helper function for ScsiPortCompleteRequest */
+VOID
+NTAPI
+SpiCompleteRequest(IN PVOID HwDeviceExtension,
+ IN PSCSI_REQUEST_BLOCK_INFO SrbInfo,
+ IN UCHAR SrbStatus)
+{
+ PSCSI_REQUEST_BLOCK Srb;
+
+ /* Get current SRB */
+ Srb = SrbInfo->Srb;
+
+ /* Return if there is no SRB or it is not active */
+ if (!Srb || !(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE)) return;
+
+ /* Set status */
+ Srb->SrbStatus = SrbStatus;
+
+ /* Set data transfered to 0 */
+ Srb->DataTransferLength = 0;
+
+ /* Notify */
+ ScsiPortNotification(RequestComplete,
+ HwDeviceExtension,
+ Srb);
+}
/*
* @unimplemented
*/
VOID NTAPI
ScsiPortCompleteRequest(IN PVOID HwDeviceExtension,
- IN UCHAR PathId,
- IN UCHAR TargetId,
- IN UCHAR Lun,
- IN UCHAR SrbStatus)
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun,
+ IN UCHAR SrbStatus)
{
- DPRINT("ScsiPortCompleteRequest()\n");
- UNIMPLEMENTED;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
+ PSCSI_REQUEST_BLOCK_INFO SrbInfo;
+ PLIST_ENTRY ListEntry;
+ ULONG BusNumber;
+ ULONG Target;
+
+ DPRINT("ScsiPortCompleteRequest() called\n");
+
+ DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+ SCSI_PORT_DEVICE_EXTENSION,
+ MiniPortDeviceExtension);
+
+ /* Go through all buses */
+ for (BusNumber = 0; BusNumber < 8; BusNumber++)
+ {
+ /* Go through all targets */
+ for (Target = 0; Target < DeviceExtension->MaxTargedIds; Target++)
+ {
+ /* Get logical unit list head */
+ LunExtension = DeviceExtension->LunExtensionList[Target % 8];
+
+ /* Go through all logical units */
+ while (LunExtension)
+ {
+ /* Now match what caller asked with what we are at now */
+ if ((PathId == SP_UNTAGGED || PathId == LunExtension->PathId)
&&
+ (TargetId == SP_UNTAGGED || TargetId == LunExtension->TargetId)
&&
+ (Lun == SP_UNTAGGED || Lun == LunExtension->Lun))
+ {
+ /* Yes, that's what caller asked for. Complete abort requests */
+ if (LunExtension->CompletedAbortRequests)
+ {
+ /* TODO: Save SrbStatus in this request */
+ DPRINT1("Completing abort request without setting
SrbStatus!\n");
+
+ /* Issue a notification request */
+ ScsiPortNotification(RequestComplete,
+ HwDeviceExtension,
+ LunExtension->CompletedAbortRequests);
+ }
+
+ /* Complete the request using our helper */
+ SpiCompleteRequest(HwDeviceExtension,
+ &LunExtension->SrbInfo,
+ SrbStatus);
+
+ /* Go through the queue and complete everything there too */
+ ListEntry = LunExtension->SrbInfo.Requests.Flink;
+ while (ListEntry != &LunExtension->SrbInfo.Requests)
+ {
+ /* Get the actual SRB info entry */
+ SrbInfo = CONTAINING_RECORD(ListEntry,
+ SCSI_REQUEST_BLOCK_INFO,
+ Requests);
+
+ /* Complete it */
+ SpiCompleteRequest(HwDeviceExtension,
+ SrbInfo,
+ SrbStatus);
+
+ /* Advance to the next request in queue */
+ ListEntry = SrbInfo->Requests.Flink;
+ }
+ }
+
+ /* Advance to the next one */
+ LunExtension = LunExtension->Next;
+ }
+ }
+ }
}
/*