Sync to trunk head(r38096)
[reactos.git] / reactos / drivers / storage / scsiport / scsiport.c
index 9d604ed..7485c13 100644 (file)
@@ -16,8 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Storage Stack
  * FILE:            drivers/storage/scsiport/scsiport.c
 
 #include "scsiport_int.h"
 
-#ifdef _MSC_VER
-  #define STDCALL
-  #define DDKAPI
-#endif
-
 ULONG InternalDebugLevel = 0x00;
 
 /* TYPES *********************************************************************/
@@ -64,29 +58,29 @@ SpiGetPciConfigData(IN PDRIVER_OBJECT DriverObject,
                     IN ULONG BusNumber,
                     IN OUT PPCI_SLOT_NUMBER NextSlotNumber);
 
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
 ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject,
                    IN PIRP Irp);
 
 static DRIVER_DISPATCH ScsiPortDispatchScsi;
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
 ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp);
 
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
 ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                      IN PIRP Irp);
 
 static DRIVER_STARTIO ScsiPortStartIo;
-static VOID STDCALL
+static VOID NTAPI
 ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
                IN PIRP Irp);
 
-static BOOLEAN STDCALL
+static BOOLEAN NTAPI
 ScsiPortStartPacket(IN OUT PVOID Context);
 
 IO_ALLOCATION_ACTION
-STDCALL
+NTAPI
 SpiAdapterControl(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                   PVOID MapRegisterBase, PVOID Context);
 
@@ -116,27 +110,33 @@ SpiGetInquiryData (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                   IN PIRP Irp);
 
 static PSCSI_REQUEST_BLOCK_INFO
-SpiGetSrbData(IN PVOID DeviceExtension,
+SpiGetSrbData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
               IN UCHAR PathId,
               IN UCHAR TargetId,
               IN UCHAR Lun,
               IN UCHAR QueueTag);
 
-static KSERVICE_ROUTINE ScsiPortIsr;
-static BOOLEAN STDCALL
+static BOOLEAN NTAPI
 ScsiPortIsr(IN PKINTERRUPT Interrupt,
            IN PVOID ServiceContext);
 
-static VOID STDCALL
+static VOID NTAPI
 ScsiPortDpcForIsr(IN PKDPC Dpc,
                  IN PDEVICE_OBJECT DpcDeviceObject,
                  IN PIRP DpcIrp,
                  IN PVOID DpcContext);
 
-static VOID STDCALL
+static VOID NTAPI
 ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject,
                PVOID Context);
 
+IO_ALLOCATION_ACTION
+NTAPI
+ScsiPortAllocateAdapterChannel(IN PDEVICE_OBJECT DeviceObject,
+                               IN PIRP Irp,
+                               IN PVOID MapRegisterBase,
+                               IN PVOID Context);
+
 static NTSTATUS
 SpiBuildDeviceMap (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                   PUNICODE_STRING RegistryPath);
@@ -149,22 +149,22 @@ SpiSendRequestSense(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                     IN PSCSI_REQUEST_BLOCK Srb);
 
 static IO_COMPLETION_ROUTINE SpiCompletionRoutine;
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 SpiCompletionRoutine(PDEVICE_OBJECT DeviceObject,
                      PIRP Irp,
                      PVOID Context);
 
 static VOID
-STDCALL
+NTAPI
 SpiProcessCompletedRequest(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                            IN PSCSI_REQUEST_BLOCK_INFO SrbInfo,
                            OUT PBOOLEAN NeedToCallStartIo);
 
-VOID STDCALL
+VOID NTAPI
 SpiGetNextRequestFromLun(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                          IN PSCSI_PORT_LUN_EXTENSION LunExtension);
 
-VOID STDCALL
+VOID NTAPI
 SpiMiniportTimerDpc(IN struct _KDPC *Dpc,
                     IN PVOID DeviceObject,
                     IN PVOID SystemArgument1,
@@ -177,7 +177,7 @@ SpiCreatePortConfig(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                     PPORT_CONFIGURATION_INFORMATION ConfigInfo,
                     BOOLEAN FirstCall);
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 SpQueryDeviceCallout(IN PVOID  Context,
                      IN PUNICODE_STRING  PathName,
                      IN INTERFACE_TYPE  BusType,
@@ -241,7 +241,7 @@ SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCa
  *     Status.
  */
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 DriverEntry(IN PDRIVER_OBJECT DriverObject,
            IN PUNICODE_STRING RegistryPath)
 {
@@ -294,25 +294,120 @@ ScsiDebugPrint(IN ULONG DebugPrintLevel,
     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 STDCALL
+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;
+            }
+        }
+    }
 }
 
 /*
  * @unimplemented
  */
-VOID STDCALL
+VOID NTAPI
 ScsiPortFlushDma(IN PVOID HwDeviceExtension)
 {
   DPRINT("ScsiPortFlushDma()\n");
@@ -323,7 +418,7 @@ ScsiPortFlushDma(IN PVOID HwDeviceExtension)
 /*
  * @implemented
  */
-VOID STDCALL
+VOID NTAPI
 ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension,
                       IN PVOID MappedAddress)
 {
@@ -336,7 +431,6 @@ ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension,
                                         SCSI_PORT_DEVICE_EXTENSION,
                                         MiniPortDeviceExtension);
 
-
     /* Initialize our pointers */
     NextMa = DeviceExtension->MappedAddressList;
     LastMa = NextMa;
@@ -376,7 +470,7 @@ ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension,
 /*
  * @implemented
  */
-ULONG STDCALL
+ULONG NTAPI
 ScsiPortGetBusData(IN PVOID DeviceExtension,
                   IN ULONG BusDataType,
                   IN ULONG SystemIoBusNumber,
@@ -384,18 +478,49 @@ ScsiPortGetBusData(IN PVOID DeviceExtension,
                   IN PVOID Buffer,
                   IN ULONG Length)
 {
-  return(HalGetBusData(BusDataType,
-                      SystemIoBusNumber,
-                      SlotNumber,
-                      Buffer,
-                      Length));
+    DPRINT("ScsiPortGetBusData()\n");
+
+    if (Length)
+    {
+        /* If Length is non-zero, just forward the call to
+        HalGetBusData() function */
+        return HalGetBusData(BusDataType,
+                             SystemIoBusNumber,
+                             SlotNumber,
+                             Buffer,
+                             Length);
+    }
+
+    /* We have a more complex case here */
+    UNIMPLEMENTED;
+    return 0;
 }
 
+/*
+ * @implemented
+ */
+ULONG NTAPI
+ScsiPortSetBusDataByOffset(IN PVOID DeviceExtension,
+                           IN ULONG BusDataType,
+                           IN ULONG SystemIoBusNumber,
+                           IN ULONG SlotNumber,
+                           IN PVOID Buffer,
+                           IN ULONG Offset,
+                           IN ULONG Length)
+{
+    DPRINT("ScsiPortSetBusDataByOffset()\n");
+    return HalSetBusDataByOffset(BusDataType,
+                                 SystemIoBusNumber,
+                                 SlotNumber,
+                                 Buffer,
+                                 Offset,
+                                 Length);
+}
 
 /*
  * @implemented
  */
-PVOID STDCALL
+PVOID NTAPI
 ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension,
                      IN INTERFACE_TYPE BusType,
                      IN ULONG SystemIoBusNumber,
@@ -427,7 +552,7 @@ ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension,
 
     /* i/o space */
     if (AddressSpace != 0)
-        return((PVOID)TranslatedAddress.u.LowPart);
+        return((PVOID)(ULONG_PTR)TranslatedAddress.QuadPart);
 
     MappedAddress = MmMapIoSpace(TranslatedAddress,
                                  NumberOfBytes,
@@ -452,9 +577,9 @@ ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension,
 }
 
 /*
- * @implemented
+ * @unimplemented
  */
-PVOID STDCALL
+PVOID NTAPI
 ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension,
                       IN UCHAR PathId,
                       IN UCHAR TargetId,
@@ -495,9 +620,9 @@ ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
-SCSI_PHYSICAL_ADDRESS STDCALL
+SCSI_PHYSICAL_ADDRESS NTAPI
 ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension,
                            IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
                            IN PVOID VirtualAddress,
@@ -563,7 +688,7 @@ ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension,
 /*
  * @unimplemented
  */
-PSCSI_REQUEST_BLOCK STDCALL
+PSCSI_REQUEST_BLOCK NTAPI
 ScsiPortGetSrb(IN PVOID DeviceExtension,
               IN UCHAR PathId,
               IN UCHAR TargetId,
@@ -579,7 +704,7 @@ ScsiPortGetSrb(IN PVOID DeviceExtension,
 /*
  * @implemented
  */
-PVOID STDCALL
+PVOID NTAPI
 ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension,
                             IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
                             IN ULONG NumberOfBytes)
@@ -761,7 +886,7 @@ SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCa
 /*
  * @implemented
  */
-PVOID STDCALL
+PVOID NTAPI
 ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension,
                           IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
 {
@@ -806,7 +931,7 @@ SpiInitOpenKeys(PCONFIGURATION_INFO ConfigInfo, PUNICODE_STRING RegistryPath)
 
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Unable to open driver's registry key %wZ, status 0x%08x\n", RegistryPath, Status);
+        DPRINT("Unable to open driver's registry key %wZ, status 0x%08x\n", RegistryPath, Status);
         ConfigInfo->ServiceKey = NULL;
     }
 
@@ -835,18 +960,21 @@ SpiInitOpenKeys(PCONFIGURATION_INFO ConfigInfo, PUNICODE_STRING RegistryPath)
         }
     }
 
-    /* Open the Device key */
-    RtlInitUnicodeString(&KeyName, L"Device");
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &KeyName,
-                               OBJ_CASE_INSENSITIVE,
-                               ConfigInfo->ServiceKey,
-                               NULL);
+    if (ConfigInfo->ServiceKey != NULL)
+    {
+        /* Open the Device key */
+        RtlInitUnicodeString(&KeyName, L"Device");
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   ConfigInfo->ServiceKey,
+                                   NULL);
 
-    /* We don't check for failure here - not needed */
-    ZwOpenKey(&ConfigInfo->DeviceKey,
-              KEY_READ,
-              &ObjectAttributes);
+        /* We don't check for failure here - not needed */
+        ZwOpenKey(&ConfigInfo->DeviceKey,
+                  KEY_READ,
+                  &ObjectAttributes);
+    }
 }
 
 
@@ -879,7 +1007,7 @@ SpiInitOpenKeys(PCONFIGURATION_INFO ConfigInfo, PUNICODE_STRING RegistryPath)
  * @implemented
  */
 
-ULONG STDCALL
+ULONG NTAPI
 ScsiPortInitialize(IN PVOID Argument1,
                   IN PVOID Argument2,
                   IN struct _HW_INITIALIZATION_DATA *HwInitializationData,
@@ -1059,7 +1187,10 @@ CreatePortConfig:
                                      FirstConfigCall);
 
         if (!NT_SUCCESS(Status))
+        {
+            DPRINT("SpiCreatePortConfig() failed with Status 0x%08X\n", Status);
             break;
+        }
 
         /* Allocate and initialize port configuration info */
         PortConfigSize = (sizeof(PORT_CONFIGURATION_INFORMATION) +
@@ -1092,8 +1223,8 @@ CreatePortConfig:
             PortConfig->AccessRanges = (PVOID)(PortConfig+1);
 
             /* Align to LONGLONG */
-            PortConfig->AccessRanges = (PVOID)((ULONG)(PortConfig->AccessRanges) + 7);
-            PortConfig->AccessRanges = (PVOID)((ULONG)(PortConfig->AccessRanges) & ~7);
+            PortConfig->AccessRanges = (PVOID)((ULONG_PTR)(PortConfig->AccessRanges) + 7);
+            PortConfig->AccessRanges = (PVOID)((ULONG_PTR)(PortConfig->AccessRanges) & ~7);
 
             /* Copy the data */
             RtlCopyMemory(PortConfig->AccessRanges,
@@ -1568,7 +1699,7 @@ CreatePortConfig:
     if (ConfigInfo.Parameter != NULL)
         ExFreePool(ConfigInfo.Parameter);
 
-    DPRINT("ScsiPortInitialize() done, Status = 0x%08X, DeviceFound = %b!\n",
+    DPRINT("ScsiPortInitialize() done, Status = 0x%08X, DeviceFound = %d!\n",
         Status, DeviceFound);
 
     return (DeviceFound == FALSE) ? Status : STATUS_SUCCESS;
@@ -1602,7 +1733,7 @@ SpiCleanupAfterInit(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
             LunInfo = DeviceExtension->BusesConfig->BusScanInfo[Bus]->LunInfo;
 
-            while (!LunInfo)
+            while (LunInfo)
             {
                 /* Free current, but save pointer to the next one */
                 Ptr = LunInfo->Next;
@@ -1642,13 +1773,11 @@ SpiCleanupAfterInit(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
             }
             else
             {
-#if 0
                 HalFreeCommonBuffer(DeviceExtension->AdapterObject,
                                     DeviceExtension->CommonBufferLength,
-                                    DeviceExtension->PhysicalCommonBuffer,
+                                    DeviceExtension->PhysicalAddress,
                                     DeviceExtension->SrbExtensionBuffer,
                                     FALSE);
-#endif
             }
     }
 
@@ -1673,12 +1802,10 @@ SpiCleanupAfterInit(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
     IoDeleteDevice(DeviceExtension->DeviceObject);
 }
 
-
-
 /*
  * @unimplemented
  */
-VOID STDCALL
+VOID NTAPI
 ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension,
                      IN PSCSI_REQUEST_BLOCK Srb,
                      IN PVOID LogicalAddress,
@@ -1688,11 +1815,10 @@ ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension,
   UNIMPLEMENTED;
 }
 
-
 /*
  * @unimplemented
  */
-VOID STDCALL
+VOID NTAPI
 ScsiPortLogError(IN PVOID HwDeviceExtension,
                 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
                 IN UCHAR PathId,
@@ -1713,11 +1839,10 @@ ScsiPortLogError(IN PVOID HwDeviceExtension,
   DPRINT("ScsiPortLogError() done\n");
 }
 
-
 /*
  * @implemented
  */
-VOID STDCALL
+VOID NTAPI
 ScsiPortMoveMemory(OUT PVOID Destination,
                   IN PVOID Source,
                   IN ULONG Length)
@@ -1809,72 +1934,68 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
         DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
         break;
 
-      case NextLuRequest:
-       {
-         UCHAR PathId;
-         UCHAR TargetId;
-         UCHAR Lun;
+    case NextLuRequest:
+        {
+            UCHAR PathId;
+            UCHAR TargetId;
+            UCHAR Lun;
+            PSCSI_PORT_LUN_EXTENSION LunExtension;
 
-         PathId = (UCHAR) va_arg (ap, int);
-         TargetId = (UCHAR) va_arg (ap, int);
-         Lun = (UCHAR) va_arg (ap, int);
+            PathId = (UCHAR) va_arg (ap, int);
+            TargetId = (UCHAR) va_arg (ap, int);
+            Lun = (UCHAR) va_arg (ap, int);
 
-         DPRINT1 ("Notify: NextLuRequest(PathId %u  TargetId %u  Lun %u)\n",
-                  PathId, TargetId, Lun);
-         /* FIXME: Implement it! */
-          ASSERT(FALSE);
+            DPRINT("Notify: NextLuRequest(PathId %u  TargetId %u  Lun %u)\n",
+                PathId, TargetId, Lun);
 
-//       DeviceExtension->IrpFlags |= IRP_FLAG_NEXT;
-//       DeviceExtension->IrpFlags |= IRP_FLAG_NEXT_LU;
+            /* Mark it in the flags field */
+            DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
 
-         /* Hack! */
-//       DeviceExtension->IrpFlags |= IRP_FLAG_NEXT;
-       }
-       break;
+            /* Get the LUN extension */
+            LunExtension = SpiGetLunExtension(DeviceExtension,
+                                              PathId,
+                                              TargetId,
+                                              Lun);
+
+            /* If returned LunExtension is NULL, break out */
+            if (!LunExtension) break;
+
+            /* This request should not be processed if */
+            if ((LunExtension->ReadyLun) ||
+                (LunExtension->SrbInfo.Srb))
+            {
+                /* Nothing to do here */
+                break;
+            }
+
+            /* Add this LUN to the list */
+            LunExtension->ReadyLun = DeviceExtension->InterruptData.ReadyLun;
+            DeviceExtension->InterruptData.ReadyLun = LunExtension;
+          }
+          break;
 
       case ResetDetected:
-       DPRINT1("Notify: ResetDetected\n");
-       /* FIXME: ??? */
-       break;
+          DPRINT("Notify: ResetDetected\n");
+          /* Add RESET flags */
+          DeviceExtension->InterruptData.Flags |=
+                SCSI_PORT_RESET | SCSI_PORT_RESET_REPORTED;
+          break;
 
       default:
        DPRINT1 ("Unsupported notification %lu\n", NotificationType);
        break;
     }
 
-  va_end(ap);
+    va_end(ap);
 
     /* Request a DPC after we're done with the interrupt */
     DeviceExtension->InterruptData.Flags |= SCSI_PORT_NOTIFICATION_NEEDED;
 }
 
-
-/*
- * @implemented
- */
-ULONG STDCALL
-ScsiPortSetBusDataByOffset(IN PVOID DeviceExtension,
-                          IN ULONG BusDataType,
-                          IN ULONG SystemIoBusNumber,
-                          IN ULONG SlotNumber,
-                          IN PVOID Buffer,
-                          IN ULONG Offset,
-                          IN ULONG Length)
-{
-  DPRINT("ScsiPortSetBusDataByOffset()\n");
-  return(HalSetBusDataByOffset(BusDataType,
-                              SystemIoBusNumber,
-                              SlotNumber,
-                              Buffer,
-                              Offset,
-                              Length));
-}
-
-
 /*
  * @implemented
  */
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 ScsiPortValidateRange(IN PVOID HwDeviceExtension,
                      IN INTERFACE_TYPE BusType,
                      IN ULONG SystemIoBusNumber,
@@ -2272,7 +2393,7 @@ SpiGetPciConfigData(IN PDRIVER_OBJECT DriverObject,
  *     Status.
  */
 
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
 ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject,
                    IN PIRP Irp)
 {
@@ -2384,7 +2505,7 @@ SpiHandleAttachRelease(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
  *     NTSTATUS
  */
 
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
 ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
 {
@@ -2625,7 +2746,7 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
  *     NTSTATUS
  */
 
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
 ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                      IN PIRP Irp)
 {
@@ -2648,7 +2769,7 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
          DPRINT("  IOCTL_SCSI_GET_DUMP_POINTERS\n");
          DumpPointers = (PDUMP_POINTERS)Irp->AssociatedIrp.SystemBuffer;
          DumpPointers->DeviceObject = DeviceObject;
-         
+
          Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
        }
        break;
@@ -2699,7 +2820,7 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
 }
 
 
-static VOID STDCALL
+static VOID NTAPI
 ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
                IN PIRP Irp)
 {
@@ -2782,7 +2903,7 @@ ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
         // Store the MDL virtual address in SrbInfo structure
         SrbInfo->DataOffset = MmGetMdlVirtualAddress(Irp->MdlAddress);
 
-        if (DeviceExtension->MapBuffers && Irp->MdlAddress)
+        if (DeviceExtension->MapBuffers)
         {
             /* Calculate offset within DataBuffer */
             SrbInfo->DataOffset = MmGetSystemAddressForMdl(Irp->MdlAddress);
@@ -2841,23 +2962,17 @@ ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
         DeviceExtension->AdapterObject != NULL &&
         !DeviceExtension->MapRegisters)
     {
-#if 0
         IoAllocateAdapterChannel(
             DeviceExtension->AdapterObject,
             DeviceObject,
             DeviceExtension->PortCapabilities.MaximumPhysicalPages,
-            ScsiPortAllocationRoutine,
+            ScsiPortAllocateAdapterChannel,
             LunExtension
             );
 
         return;
-#else
-        /* TODO: DMA is not implemented yet */
-        ASSERT(FALSE);
-#endif
     }
 
-
     KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
 
     if (!KeSynchronizeExecution(DeviceExtension->Interrupt,
@@ -2872,14 +2987,18 @@ ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
 
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
     }
+    else
+    {
+        /* Release the spinlock only */
+        KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
+    }
 
-    KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
 
     DPRINT("ScsiPortStartIo() done\n");
 }
 
 
-static BOOLEAN STDCALL
+static BOOLEAN NTAPI
 ScsiPortStartPacket(IN OUT PVOID Context)
 {
     PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
@@ -2887,6 +3006,7 @@ ScsiPortStartPacket(IN OUT PVOID Context)
     PSCSI_REQUEST_BLOCK Srb;
     PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
     PSCSI_PORT_LUN_EXTENSION LunExtension;
+    PSCSI_REQUEST_BLOCK_INFO SrbInfo;
     BOOLEAN Result;
     BOOLEAN StartTimer;
 
@@ -2936,8 +3056,6 @@ ScsiPortStartPacket(IN OUT PVOID Context)
         /* Is this an abort request? */
         if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND)
         {
-            PSCSI_REQUEST_BLOCK_INFO SrbInfo;
-
             /* Get pointer to SRB info structure */
             SrbInfo = SpiGetSrbData(DeviceExtension,
                                     Srb->PathId,
@@ -3010,8 +3128,13 @@ ScsiPortStartPacket(IN OUT PVOID Context)
         /* If it's tagged - special thing */
         if (Srb->QueueTag != SP_UNTAGGED)
         {
-            /* TODO: Support tagged requests */
-            ASSERT(FALSE);
+            SrbInfo = &DeviceExtension->SrbInfo[Srb->QueueTag - 1];
+
+            /* Chek for consistency */
+            ASSERT(SrbInfo->Requests.Blink == NULL);
+
+            /* Insert it into the list of requests */
+            InsertTailList(&LunExtension->SrbInfo.Requests, &SrbInfo->Requests);
         }
     }
 
@@ -3030,7 +3153,7 @@ ScsiPortStartPacket(IN OUT PVOID Context)
 }
 
 IO_ALLOCATION_ACTION
-STDCALL
+NTAPI
 SpiAdapterControl(PDEVICE_OBJECT DeviceObject,
                   PIRP Irp,
                   PVOID MapRegisterBase,
@@ -3054,7 +3177,7 @@ SpiAdapterControl(PDEVICE_OBJECT DeviceObject,
     IrpStack = IoGetCurrentIrpStackLocation(Irp);
     Srb = (PSCSI_REQUEST_BLOCK)IrpStack->Parameters.Others.Argument1;
 
-    /* Depending on the map registers number, we allocate 
+    /* Depending on the map registers number, we allocate
        either from NonPagedPool, or from our static list */
     if (SrbInfo->NumberOfMapRegisters > MAX_SG_LIST)
     {
@@ -3087,8 +3210,11 @@ SpiAdapterControl(PDEVICE_OBJECT DeviceObject,
     /* Build the actual SG list */
     while (TotalLength < Srb->DataTransferLength)
     {
+        if (!ScatterGatherList)
+            break;
+
         ScatterGatherList->Length = Srb->DataTransferLength - TotalLength;
-        ScatterGatherList->PhysicalAddress = IoMapTransfer(DeviceExtension->AdapterObject,
+        ScatterGatherList->PhysicalAddress = IoMapTransfer(NULL,
                                                            Irp->MdlAddress,
                                                            MapRegisterBase,
                                                            DataVA + TotalLength,
@@ -3649,7 +3775,7 @@ SpiScanAdapter(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
             /* Scan all logical units */
             for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
             {
-                if (!LunExtension)
+                if ((!LunExtension) || (!LunInfo))
                     break;
 
                 /* Add extension to the list */
@@ -3683,7 +3809,7 @@ SpiScanAdapter(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
                     /* Check if this device is unsupported */
                     if (InquiryData->DeviceTypeQualifier == DEVICE_QUALIFIER_NOT_SUPPORTED)
                     {
-                        DeviceExtension->LunExtensionList[Hint] = 
+                        DeviceExtension->LunExtensionList[Hint] =
                             DeviceExtension->LunExtensionList[Hint]->Next;
 
                         continue;
@@ -3727,7 +3853,7 @@ SpiScanAdapter(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
                 else
                 {
                     /* Remove this LUN from the list */
-                    DeviceExtension->LunExtensionList[Hint] = 
+                    DeviceExtension->LunExtensionList[Hint] =
                         DeviceExtension->LunExtensionList[Hint]->Next;
 
                     /* Decide whether we are continuing or not */
@@ -3791,7 +3917,7 @@ SpiGetInquiryData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
     /* Calculate data size */
     Length = sizeof(SCSI_ADAPTER_BUS_INFO) + (BusCount - 1) *
         sizeof(SCSI_BUS_DATA);
-    
+
     Length += InquiryDataSize * LunCount;
 
     /* Check, if all data is going to fit into provided buffer */
@@ -3871,7 +3997,7 @@ SpiGetInquiryData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
 }
 
 static PSCSI_REQUEST_BLOCK_INFO
-SpiGetSrbData(IN PVOID DeviceExtension,
+SpiGetSrbData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
               IN UCHAR PathId,
               IN UCHAR TargetId,
               IN UCHAR Lun,
@@ -3896,9 +4022,11 @@ SpiGetSrbData(IN PVOID DeviceExtension,
     }
     else
     {
-        /* TODO: Implement when we have it */
-        ASSERT(FALSE);
-        return NULL;
+        /* Make sure the tag is valid, if it is - return the data */
+        if (QueueTag > DeviceExtension->SrbDataCount || QueueTag < 1)
+            return NULL;
+        else
+            return &DeviceExtension->SrbInfo[QueueTag -1];
     }
 }
 
@@ -3935,6 +4063,12 @@ SpiSendRequestSense(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                            TRUE,
                            TRUE);
 
+    if (!Srb)
+    {
+        DPRINT("SpiSendRequestSense() failed, Srb %p\n", Srb);
+        return;
+    }
+
     IrpStack = IoGetNextIrpStackLocation(Irp);
     IrpStack->MajorFunction = IRP_MJ_SCSI;
 
@@ -4001,7 +4135,7 @@ SpiSendRequestSense(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
 
 static
 VOID
-STDCALL
+NTAPI
 SpiProcessCompletedRequest(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                            IN PSCSI_REQUEST_BLOCK_INFO SrbInfo,
                            OUT PBOOLEAN NeedToCallStartIo)
@@ -4038,7 +4172,6 @@ SpiProcessCompletedRequest(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
         }
     }
 
-
     /* Flush adapter if needed */
     if (SrbInfo->BaseOfMapRegister)
     {
@@ -4155,7 +4288,7 @@ SpiProcessCompletedRequest(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
             KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
         }
 
-        DPRINT("IoCompleting request IRP 0x%08X\n", Irp);
+        DPRINT("IoCompleting request IRP 0x%p\n", Irp);
 
         IoCompleteRequest(Irp, IO_DISK_INCREMENT);
 
@@ -4319,7 +4452,7 @@ Error:
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 SpiCompletionRoutine(PDEVICE_OBJECT DeviceObject,
                      PIRP Irp,
                      PVOID Context)
@@ -4365,7 +4498,7 @@ SpiCompletionRoutine(PDEVICE_OBJECT DeviceObject,
 
     if (Irp->MdlAddress != NULL)
     {
-        MmUnlockPages(Irp->MdlAddress);
+               MmUnlockPages(Irp->MdlAddress);
         IoFreeMdl(Irp->MdlAddress);
         Irp->MdlAddress = NULL;
     }
@@ -4374,9 +4507,7 @@ SpiCompletionRoutine(PDEVICE_OBJECT DeviceObject,
     return STATUS_MORE_PROCESSING_REQUIRED;
 }
 
-
-
-static BOOLEAN STDCALL
+static BOOLEAN NTAPI
 ScsiPortIsr(IN PKINTERRUPT Interrupt,
             IN PVOID ServiceContext)
 {
@@ -4406,7 +4537,7 @@ ScsiPortIsr(IN PKINTERRUPT Interrupt,
 }
 
 BOOLEAN
-STDCALL
+NTAPI
 SpiSaveInterruptData(IN PVOID Context)
 {
     PSCSI_PORT_SAVE_INTERRUPT InterruptContext = Context;
@@ -4524,7 +4655,7 @@ SpiSaveInterruptData(IN PVOID Context)
 }
 
 VOID
-STDCALL
+NTAPI
 SpiGetNextRequestFromLun(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
                          IN PSCSI_PORT_LUN_EXTENSION LunExtension)
 {
@@ -4631,7 +4762,7 @@ SpiGetNextRequestFromLun(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
 //    IN PIRP           DpcIrp
 //    IN PVOID          DpcContext
 //
-static VOID STDCALL
+static VOID NTAPI
 ScsiPortDpcForIsr(IN PKDPC Dpc,
                  IN PDEVICE_OBJECT DpcDeviceObject,
                  IN PIRP DpcIrp,
@@ -4831,7 +4962,7 @@ TryAgain:
 }
 
 BOOLEAN
-STDCALL
+NTAPI
 SpiProcessTimeout(PVOID ServiceContext)
 {
     PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext;
@@ -4877,7 +5008,7 @@ SpiProcessTimeout(PVOID ServiceContext)
 
 
 BOOLEAN
-STDCALL
+NTAPI
 SpiResetBus(PVOID ServiceContext)
 {
     PRESETBUS_PARAMS ResetParams = (PRESETBUS_PARAMS)ServiceContext;
@@ -4910,7 +5041,7 @@ SpiResetBus(PVOID ServiceContext)
 //    IN  PVOID           Context       the Controller extension for the
 //                                      controller the device is on
 //
-static VOID STDCALL
+static VOID NTAPI
 ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject,
                 PVOID Context)
 {
@@ -5434,13 +5565,14 @@ ByeBye:
 }
 
 VOID
-STDCALL
+NTAPI
 SpiMiniportTimerDpc(IN struct _KDPC *Dpc,
                     IN PVOID DeviceObject,
                     IN PVOID SystemArgument1,
                     IN PVOID SystemArgument2)
 {
     DPRINT1("Miniport timer DPC\n");
+    ASSERT(FALSE);
 }
 
 static NTSTATUS
@@ -5568,12 +5700,16 @@ TryNextAd:
             else
             {
                 /* Info was not found, exit */
+                DPRINT1("ZwOpenKey() failed with Status=0x%08X\n", Status);
                 return STATUS_DEVICE_DOES_NOT_EXIST;
             }
         }
+        else
+        {
+            DPRINT1("ZwOpenKey() failed with Status=0x%08X\n", Status);
+        }
     }
 
-
     /* Look at device params */
     Key = NULL;
     if (InternalConfigInfo->Parameter)
@@ -5700,7 +5836,6 @@ SpiParseDeviceInfo(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
     ANSI_STRING AnsiString;
     NTSTATUS Status = STATUS_SUCCESS;
 
-
     KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION) Buffer;
 
     /* Loop through all values in the device node */
@@ -6021,9 +6156,8 @@ SpiParseDeviceInfo(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
     }
 }
 
-
 NTSTATUS
-STDCALL
+NTAPI
 SpQueryDeviceCallout(IN PVOID  Context,
                      IN PUNICODE_STRING  PathName,
                      IN INTERFACE_TYPE  BusType,
@@ -6043,7 +6177,31 @@ SpQueryDeviceCallout(IN PVOID  Context,
     return STATUS_SUCCESS;
 }
 
+IO_ALLOCATION_ACTION
+NTAPI
+ScsiPortAllocateAdapterChannel(IN PDEVICE_OBJECT DeviceObject,
+                               IN PIRP Irp,
+                               IN PVOID MapRegisterBase,
+                               IN PVOID Context)
+{
+    KIRQL Irql;
+    PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
 
+    /* Guard access with the spinlock */
+    KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
+
+    /* Save MapRegisterBase we've got here */
+    DeviceExtension->MapRegisterBase = MapRegisterBase;
+
+    /* Start pending request */
+    KeSynchronizeExecution(DeviceExtension->Interrupt,
+        ScsiPortStartPacket, DeviceObject);
+
+    /* Release spinlock we took */
+    KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
+
+    return KeepObject;
+}
 
 static
 NTSTATUS
@@ -6054,7 +6212,7 @@ SpiStatusSrbToNt(UCHAR SrbStatus)
     case SRB_STATUS_TIMEOUT:
     case SRB_STATUS_COMMAND_TIMEOUT:
         return STATUS_IO_TIMEOUT;
-    
+
     case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
     case SRB_STATUS_BAD_FUNCTION:
         return STATUS_INVALID_DEVICE_REQUEST;
@@ -6083,7 +6241,7 @@ SpiStatusSrbToNt(UCHAR SrbStatus)
 /*
  * @implemented
  */
-ULONG STDCALL
+ULONG NTAPI
 ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address)
 {
   DPRINT("ScsiPortConvertPhysicalAddressToUlong()\n");