#include <ddk/srb.h>
#include <ddk/scsi.h>
#include <ddk/ntddscsi.h>
-#include <ntos/minmax.h>
-#include <rosrtl/string.h>
+#include <ddk/ntddstor.h>
+#include <ddk/ntdddisk.h>
+#include <stdio.h>
#define NDEBUG
#include <debug.h>
PSCSI_REQUEST_BLOCK Srb);
+static NTSTATUS
+SpiScsiMiniport(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
/* FUNCTIONS *****************************************************************/
/**********************************************************************
/*
* @implemented
*/
+#undef ScsiPortConvertPhysicalAddressToUlong
ULONG STDCALL
ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address)
{
}
if (Srb == NULL)
{
- EndAddress = DeviceExtension->VirtualAddress + DeviceExtension->CommonBufferLength;
+ EndAddress = (PVOID)((ULONG_PTR)DeviceExtension->VirtualAddress + DeviceExtension->CommonBufferLength);
if (VirtualAddress >= DeviceExtension->VirtualAddress && VirtualAddress < EndAddress)
{
Offset = (ULONG_PTR)VirtualAddress - (ULONG_PTR)DeviceExtension->VirtualAddress;
}
else
{
- EndAddress = Srb->DataBuffer + Srb->DataTransferLength;
+ EndAddress = (PVOID)((ULONG_PTR)Srb->DataBuffer + Srb->DataTransferLength);
if (VirtualAddress == NULL)
{
VirtualAddress = Srb->DataBuffer;
}
else if (VirtualAddress < Srb->DataBuffer || VirtualAddress >= EndAddress)
{
- EndAddress = Srb->SenseInfoBuffer + Srb->SenseInfoBufferLength;
+ EndAddress = (PVOID)((ULONG_PTR)Srb->SenseInfoBuffer + Srb->SenseInfoBufferLength);
if (VirtualAddress < Srb->SenseInfoBuffer || VirtualAddress >= EndAddress)
{
PhysicalAddress.QuadPart = 0LL;
}
BufferLength = PAGE_SIZE - (ULONG_PTR)VirtualAddress % PAGE_SIZE;
- while (VirtualAddress + BufferLength < EndAddress)
+ while ((ULONG_PTR)VirtualAddress + BufferLength < (ULONG_PTR)EndAddress)
{
- NextPhysicalAddress = MmGetPhysicalAddress(VirtualAddress + BufferLength);
+ NextPhysicalAddress = MmGetPhysicalAddress((PVOID)((ULONG_PTR)VirtualAddress + BufferLength));
if (PhysicalAddress.QuadPart + BufferLength != NextPhysicalAddress.QuadPart)
{
break;
}
BufferLength += PAGE_SIZE;
}
- if (VirtualAddress + BufferLength >= EndAddress)
+ if ((ULONG_PTR)VirtualAddress + BufferLength >= (ULONG_PTR)EndAddress)
{
- BufferLength = EndAddress - VirtualAddress;
+ BufferLength = (ULONG)((ULONG_PTR)EndAddress - (ULONG_PTR)VirtualAddress);
}
}
if (Length != NULL)
DPRINT ("Created device: %wZ (%p)\n", &DeviceName, PortDeviceObject);
+ /* Increase the stacksize. We reenter our device on IOCTL_SCSI_MINIPORT */
+ PortDeviceObject->StackSize++;
+
/* Set the buffering strategy here... */
PortDeviceObject->Flags |= DO_DIRECT_IO;
PortDeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
PortConfig->DemandMode = FALSE;
PortConfig->MapBuffers = HwInitializationData->MapBuffers;
PortConfig->NeedPhysicalAddresses = HwInitializationData->NeedPhysicalAddresses;
- PortConfig->TaggedQueuing = HwInitializationData->TaggedQueueing;
+ PortConfig->TaggedQueuing = HwInitializationData->TaggedQueuing;
PortConfig->AutoRequestSense = HwInitializationData->AutoRequestSense;
PortConfig->MultipleRequestPerLu = HwInitializationData->MultipleRequestPerLu;
PortConfig->ReceiveEvent = HwInitializationData->ReceiveEvent;
PortConfig->SrbExtensionSize = HwInitializationData->SrbExtensionSize;
PortConfig->SpecificLuExtensionSize = HwInitializationData->SpecificLuExtensionSize;
- PortConfig->AccessRanges = (PACCESS_RANGE)(PortConfig + 1);
+ PortConfig->AccessRanges = (ACCESS_RANGE(*)[])(PortConfig + 1);
/* Search for matching PCI device */
if ((HwInitializationData->AdapterInterfaceType == PCIBus) &&
for (i = 0; i < PortConfig->NumberOfAccessRanges; i++)
{
- PortConfig->AccessRanges[i].RangeStart.QuadPart =
+ (*PortConfig->AccessRanges)[i].RangeStart.QuadPart =
PciConfig.u.type0.BaseAddresses[i] & PCI_ADDRESS_IO_ADDRESS_MASK;
- if (PortConfig->AccessRanges[i].RangeStart.QuadPart != 0)
+ if ((*PortConfig->AccessRanges)[i].RangeStart.QuadPart != 0)
{
RangeLength = (ULONG)-1;
HalSetBusDataByOffset (PCIConfiguration,
sizeof(ULONG));
if (RangeLength != 0)
{
- PortConfig->AccessRanges[i].RangeLength =
+ (*PortConfig->AccessRanges)[i].RangeLength =
-(RangeLength & PCI_ADDRESS_IO_ADDRESS_MASK);
- PortConfig->AccessRanges[i].RangeInMemory =
+ (*PortConfig->AccessRanges)[i].RangeInMemory =
!(PciConfig.u.type0.BaseAddresses[i] & PCI_ADDRESS_IO_SPACE);
DPRINT("RangeStart 0x%lX RangeLength 0x%lX RangeInMemory %s\n",
{
PIO_STACK_LOCATION Stack;
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ScsiPortDeviceControl()\n");
- Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
DPRINT("Inquiry data size: %lu\n", Irp->IoStatus.Information);
}
break;
+
+ case IOCTL_SCSI_PASS_THROUGH:
+ DPRINT(" IOCTL_SCSI_PASS_THROUGH\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case IOCTL_SCSI_PASS_THROUGH_DIRECT:
+ DPRINT(" IOCTL_SCSI_PASS_THROUGH_DIRECT\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case IOCTL_SCSI_MINIPORT:
+ DPRINT1(" IOCTL_SCSI_MINIPORT\n");
+ DPRINT1(" Signature: %.8s\n", ((PSRB_IO_CONTROL)Irp->AssociatedIrp.SystemBuffer)->Signature);
+ DPRINT1(" ControlCode: 0x%lX\n", ((PSRB_IO_CONTROL)Irp->AssociatedIrp.SystemBuffer)->ControlCode);
+ return SpiScsiMiniport(DeviceObject, Irp);
default:
DPRINT1(" unknown ioctl code: 0x%lX\n",
Stack->Parameters.DeviceIoControl.IoControlCode);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
+ Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return(STATUS_SUCCESS);
+ return Status;
+}
+
+static NTSTATUS STDCALL
+SpiCompletion(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ PSCSI_REQUEST_BLOCK Srb;
+
+ DPRINT("SpiCompletion(DeviceObject %x, Irp %x, Context %x)\n",
+ DeviceObject, Irp, Context);
+
+ Srb = (PSCSI_REQUEST_BLOCK)Context;
+ Irp->IoStatus.Information = 0;
+
+ switch (SRB_STATUS(Srb->SrbStatus))
+ {
+ case SRB_STATUS_SUCCESS:
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = Srb->DataTransferLength;
+ break;
+
+ case SRB_STATUS_INVALID_PATH_ID:
+ case SRB_STATUS_INVALID_TARGET_ID:
+ case SRB_STATUS_INVALID_LUN:
+ case SRB_STATUS_NO_HBA:
+ Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
+ break;
+
+ case SRB_STATUS_NO_DEVICE:
+ Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
+ break;
+
+ case SRB_STATUS_BUSY:
+ Irp->IoStatus.Status = STATUS_DEVICE_BUSY;
+ break;
+
+ case SRB_STATUS_DATA_OVERRUN:
+ Irp->IoStatus.Status = STATUS_DATA_OVERRUN;
+ Irp->IoStatus.Information = Srb->DataTransferLength;
+ break;
+
+ case SRB_STATUS_INVALID_REQUEST:
+ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+
+ default:
+ Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
+ break;
+ }
+
+ ExFreePool(Srb);
+
+ if (Irp->PendingReturned)
+ {
+ IoMarkIrpPending (Irp);
+ }
+ return Irp->IoStatus.Status;
+}
+
+static NTSTATUS
+SpiScsiMiniport(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ PSRB_IO_CONTROL SrbIoControl;
+ PIO_STACK_LOCATION IrpStack;
+ PSCSI_REQUEST_BLOCK Srb;
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
+
+ DPRINT("SpiScsiMiniport(DeviceObject %x, Irp %x)\n",
+ DeviceObject, Irp);
+
+ DeviceExtension = DeviceObject->DeviceExtension;
+ SrbIoControl = (PSRB_IO_CONTROL)Irp->AssociatedIrp.SystemBuffer;
+
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1)
+ {
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_INVALID_PARAMETER;
+ }
+ if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SRB_IO_CONTROL) + SrbIoControl->Length)
+ {
+ Irp->IoStatus.Information = sizeof(SRB_IO_CONTROL) + SrbIoControl->Length;
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+ if (IsListEmpty(&DeviceExtension->LunExtensionListHead))
+ {
+ Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+ Srb = ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK));
+ if (Srb == NULL)
+ {
+ Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
+ Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
+ Srb->OriginalRequest = Irp;
+ Srb->Function = SRB_FUNCTION_IO_CONTROL;
+ Srb->DataBuffer = (PVOID)SrbIoControl;
+ Srb->DataTransferLength = sizeof(SRB_IO_CONTROL) + SrbIoControl->Length;
+
+ /* We using the first extension from the list. The miniport driver is responsible to find the correct device. */
+ LunExtension = CONTAINING_RECORD(DeviceExtension->LunExtensionListHead.Flink,
+ SCSI_PORT_LUN_EXTENSION,
+ List);
+ Srb->PathId = LunExtension->PathId;
+ Srb->TargetId = LunExtension->TargetId;
+ Srb->Lun = LunExtension->Lun;
+
+ IrpStack = IoGetNextIrpStackLocation(Irp);
+
+ IrpStack->MajorFunction = IRP_MJ_SCSI;
+ IrpStack->Parameters.Scsi.Srb = Srb;
+
+ IoSetCompletionRoutine(Irp,
+ SpiCompletion,
+ Srb,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ return IoCallDriver(DeviceObject, Irp);
}
static VOID
if (index != 0xffffffff)
{
DeviceExtension->CurrentSrbExtensions++;
- Srb->SrbExtension = DeviceExtension->VirtualAddress + index * DeviceExtension->SrbExtensionSize;
+ Srb->SrbExtension = (PVOID)((ULONG_PTR)DeviceExtension->VirtualAddress + index * DeviceExtension->SrbExtensionSize);
}
}
DPRINT("%x\n", Srb->SrbExtension);
{
PSCSI_PORT_LUN_EXTENSION LunExtension;
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
+ UNICODE_STRING KeyName =
+ RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
UNICODE_STRING ValueName;
WCHAR NameBuffer[64];
ULONG Disposition;
}
/* Open or create the 'Scsi' subkey */
- RtlRosInitUnicodeStringFromLiteral(&KeyName,
- L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
}
/* Set 'IOAddress' (REG_DWORD) value (NT4 only) */
- UlongData = ScsiPortConvertPhysicalAddressToUlong(DeviceExtension->PortConfig->AccessRanges[0].RangeStart);
+ UlongData = ScsiPortConvertPhysicalAddressToUlong((*DeviceExtension->PortConfig->AccessRanges)[0].RangeStart);
DPRINT(" IOAddress = %lx\n", UlongData);
RtlInitUnicodeString(&ValueName,
L"IOAddress");
if (Srb->SrbStatus == SRB_STATUS_BUSY)
{
+ CompleteThisRequest = FALSE;
+ Irp->Tail.Overlay.DriverContext[3] = Srb;
+
SpiRemoveActiveIrp(DeviceExtension, Irp, PrevIrp);
SpiFreeSrbExtension(DeviceExtension, OriginalSrb);
+
+ Srb->OriginalRequest = LunExtension;
+ Irp->Tail.Overlay.DriverContext[2] = 0;
+
InsertHeadList(&DeviceExtension->PendingIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
DeviceExtension->PendingIrpCount++;
LunExtension->PendingIrpCount++;
SenseInfoBuffer,
sizeof(SENSE_DATA));
OriginalSrb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
+ OriginalSrb->SrbExtension = Srb->SrbExtension;
ExFreePool(Srb);
CompleteThisRequest = TRUE;
}
CompleteThisRequest = FALSE;
Irp->Tail.Overlay.DriverContext[3] = Srb;
SpiRemoveActiveIrp(DeviceExtension, Irp, PrevIrp);
- SpiFreeSrbExtension(DeviceExtension, Srb);
+ SpiFreeSrbExtension(DeviceExtension, OriginalSrb);
Srb->OriginalRequest = LunExtension;
Irp->Tail.Overlay.DriverContext[2] = 0;