[SCSIPORT]
[reactos.git] / reactos / drivers / storage / scsiport / scsiport.c
index 905773c..74b787b 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Storage Stack
  * FILE:            drivers/storage/scsiport/scsiport.c
  * PURPOSE:         SCSI port driver
- * PROGRAMMER:      Eric Kohl (ekohl@rz-online.de)
+ * PROGRAMMER:      Eric Kohl
  *                  Aleksey Bragin (aleksey reactos org)
  */
 
@@ -45,6 +45,8 @@
 
 ULONG InternalDebugLevel = 0x00;
 
+#undef ScsiPortMoveMemory
+
 /* TYPES *********************************************************************/
 
 /* GLOBALS *******************************************************************/
@@ -216,7 +218,9 @@ SpiHandleAttachRelease(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
 static NTSTATUS
 SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCachedSize);
 
-
+NTHALAPI ULONG NTAPI HalGetBusData(BUS_DATA_TYPE, ULONG, ULONG, PVOID, ULONG);
+NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY);
+NTHALAPI NTSTATUS NTAPI HalAssignSlotResources(PUNICODE_STRING, PUNICODE_STRING, PDRIVER_OBJECT, PDEVICE_OBJECT, INTERFACE_TYPE, ULONG, ULONG, PCM_RESOURCE_LIST *);
 
 /* FUNCTIONS *****************************************************************/
 
@@ -552,7 +556,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,
@@ -1223,8 +1227,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,
@@ -1981,8 +1985,27 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
                 SCSI_PORT_RESET | SCSI_PORT_RESET_REPORTED;
           break;
 
+      case CallDisableInterrupts:
+          DPRINT1("UNIMPLEMENTED SCSI Notification called: CallDisableInterrupts!\n");
+          break;
+
+      case CallEnableInterrupts:
+          DPRINT1("UNIMPLEMENTED SCSI Notification called: CallEnableInterrupts!\n");
+          break;
+
+      case RequestTimerCall:
+          DPRINT("Notify: RequestTimerCall\n");
+          DeviceExtension->InterruptData.Flags |= SCSI_PORT_TIMER_NEEDED;
+          DeviceExtension->InterruptData.HwScsiTimer = (PHW_TIMER)va_arg(ap, PHW_TIMER);
+          DeviceExtension->InterruptData.MiniportTimerValue = (ULONG)va_arg(ap, ULONG);
+          break;
+
+      case BusChangeDetected:
+          DPRINT1("UNIMPLEMENTED SCSI Notification called: BusChangeDetected!\n");
+          break;
+      
       default:
-       DPRINT1 ("Unsupported notification %lu\n", NotificationType);
+       DPRINT1 ("Unsupported notification from WMI: %lu\n", NotificationType);
        break;
     }
 
@@ -2752,7 +2775,7 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
 {
     PIO_STACK_LOCATION Stack;
     PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
-    NTSTATUS Status = STATUS_SUCCESS;;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     DPRINT("ScsiPortDeviceControl()\n");
 
@@ -2806,6 +2829,14 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
           Status = SpiGetInquiryData(DeviceExtension, Irp);
           break;
 
+      case IOCTL_SCSI_MINIPORT:
+          DPRINT1("IOCTL_SCSI_MINIPORT unimplemented!\n");
+          break;
+
+      case IOCTL_SCSI_PASS_THROUGH:
+          DPRINT1("IOCTL_SCSI_PASS_THROUGH unimplemented!\n");
+          break;
+
       default:
        DPRINT1("  unknown ioctl code: 0x%lX\n",
               Stack->Parameters.DeviceIoControl.IoControlCode);
@@ -4774,6 +4805,7 @@ ScsiPortDpcForIsr(IN PKDPC Dpc,
     PSCSI_PORT_LUN_EXTENSION LunExtension;
     BOOLEAN NeedToStartIo;
     PSCSI_REQUEST_BLOCK_INFO SrbInfo;
+    LARGE_INTEGER TimerValue;
 
     DPRINT("ScsiPortDpcForIsr(Dpc %p  DpcDeviceObject %p  DpcIrp %p  DpcContext %p)\n",
            Dpc, DpcDeviceObject, DpcIrp, DpcContext);
@@ -4814,10 +4846,26 @@ TryAgain:
     }
 
     /* Check if timer is needed */
-    if (InterruptData.Flags & SCIS_PORT_TIMER_NEEDED)
+    if (InterruptData.Flags & SCSI_PORT_TIMER_NEEDED)
     {
-        /* TODO: Implement */
-        ASSERT(FALSE);
+        /* Save the timer routine */
+        DeviceExtension->HwScsiTimer = InterruptData.HwScsiTimer;
+
+        if (InterruptData.MiniportTimerValue == 0)
+        {
+            /* Cancel the timer */
+            KeCancelTimer(&DeviceExtension->MiniportTimer);
+        }
+        else
+        {
+            /* Convert timer value */
+            TimerValue.QuadPart = Int32x32To64(InterruptData.MiniportTimerValue, -10);
+
+            /* Set the timer */
+            KeSetTimer(&DeviceExtension->MiniportTimer,
+                       TimerValue,
+                       &DeviceExtension->MiniportTimerDpc);
+        }
     }
 
     /* If it's ready for the next request */
@@ -5571,8 +5619,31 @@ SpiMiniportTimerDpc(IN struct _KDPC *Dpc,
                     IN PVOID SystemArgument1,
                     IN PVOID SystemArgument2)
 {
-    DPRINT1("Miniport timer DPC\n");
-    ASSERT(FALSE);
+    PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+
+    DPRINT("Miniport timer DPC\n");
+
+    DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
+
+    /* Acquire the spinlock */
+    KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
+
+    /* Call the timer routine */
+    if (DeviceExtension->HwScsiTimer != NULL)
+    {
+        DeviceExtension->HwScsiTimer(&DeviceExtension->MiniPortDeviceExtension);
+    }
+
+    /* Release the spinlock */
+    KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
+
+    if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
+    {
+        ScsiPortDpcForIsr(NULL,
+                          DeviceExtension->DeviceObject,
+                          NULL,
+                          NULL);
+    }
 }
 
 static NTSTATUS