-/* $Id: class2.c,v 1.4 2002/01/31 14:57:58 ekohl Exp $
+/*
+ * ReactOS kernel
+ * Copyright (C) 2001, 2002 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * 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.
+ */
+/* $Id: class2.c,v 1.10 2002/03/08 11:59:49 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
- PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
- LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
- LARGE_INTEGER startingBlock;
+ PDEVICE_EXTENSION DeviceExtension;
+ PIO_STACK_LOCATION CurrentIrpStack;
+ PIO_STACK_LOCATION NextIrpStack;
+ LARGE_INTEGER StartingOffset;
+ LARGE_INTEGER StartingBlock;
PSCSI_REQUEST_BLOCK Srb;
- PCDB Cdb;
- ULONG logicalBlockAddress;
- USHORT transferBlocks;
-
- //
- // Calculate relative sector address.
- //
+ PCDB Cdb;
+ ULONG LogicalBlockAddress;
+ USHORT TransferBlocks;
-// logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
+ DeviceExtension = DeviceObject->DeviceExtension;
+ CurrentIrpStack = IoGetCurrentIrpStackLocation(Irp);
+ NextIrpStack = IoGetNextIrpStackLocation(Irp);
+ StartingOffset = CurrentIrpStack->Parameters.Read.ByteOffset;
- startingBlock.QuadPart = startingOffset.QuadPart >> deviceExtension->SectorShift;
- logicalBlockAddress = (ULONG)startingBlock.u.LowPart;
+ /* calculate logical block address */
+ StartingBlock.QuadPart = StartingOffset.QuadPart / 512; // >> deviceExtension->SectorShift;
+ LogicalBlockAddress = (ULONG)StartingBlock.u.LowPart;
- //
- // Allocate an Srb.
- //
+ DPRINT("Logical block address: %lu\n", LogicalBlockAddress);
-// Srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
+ /* allocate and initialize an SRB */
+ /* FIXME: use lookaside list instead */
Srb = ExAllocatePool(NonPagedPool,
sizeof(SCSI_REQUEST_BLOCK));
-
Srb->SrbFlags = 0;
-
- //
- // Write length to SRB.
- //
-
Srb->Length = sizeof(SCSI_REQUEST_BLOCK); //SCSI_REQUEST_BLOCK_SIZE;
+ Srb->OriginalRequest = Irp;
+ Srb->PathId = DeviceExtension->PathId;
+ Srb->TargetId = DeviceExtension->TargetId;
+ Srb->Lun = DeviceExtension->Lun;
+ Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+ Srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
+ Srb->DataTransferLength = CurrentIrpStack->Parameters.Read.Length;
+ Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
+ Srb->QueueSortKey = LogicalBlockAddress;
- //
- // Set up IRP Address.
- //
-
- Srb->OriginalRequest = Irp;
-
- //
- // Set up target ID and logical unit number.
- //
-
- Srb->PathId = deviceExtension->PathId;
- Srb->TargetId = deviceExtension->TargetId;
- Srb->Lun = deviceExtension->Lun;
- Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
- Srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
-
- //
- // Save byte count of transfer in SRB Extension.
- //
-
- Srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
-
- //
- // Initialize the queue actions field.
- //
-
- Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
-
- //
- // Queue sort key is Relative Block Address.
- //
-
- Srb->QueueSortKey = logicalBlockAddress;
-
- //
- // Indicate auto request sense by specifying buffer and size.
- //
-
- Srb->SenseInfoBuffer = deviceExtension->SenseData;
- Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
-
- //
- // Set timeout value of one unit per 64k bytes of data.
- //
-
- Srb->TimeOutValue = ((Srb->DataTransferLength + 0xFFFF) >> 16) *
- deviceExtension->TimeOutValue;
-
- //
- // Zero statuses.
- //
-
- Srb->SrbStatus = 0;
- Srb->ScsiStatus = 0;
- Srb->NextSrb = 0;
-
- //
- // Indicate that 10-byte CDB's will be used.
- //
-
- Srb->CdbLength = 10;
+ Srb->SenseInfoBuffer = DeviceExtension->SenseData;
+ Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
- //
- // Fill in CDB fields.
- //
+ Srb->TimeOutValue =
+ ((Srb->DataTransferLength + 0xFFFF) >> 16) * DeviceExtension->TimeOutValue;
- Cdb = (PCDB)Srb->Cdb;
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ Srb->ScsiStatus = 0;
+ Srb->NextSrb = 0;
- //
- // Zero 12 bytes for Atapi Packets
- //
+ Srb->CdbLength = 10;
+ Cdb = (PCDB)Srb->Cdb;
+ /* Initialize ATAPI packet (12 bytes) */
RtlZeroMemory(Cdb,
MAXIMUM_CDB_SIZE);
- Cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
- transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
-
- //
- // Move little endian values into CDB in big endian format.
- //
+ Cdb->CDB10.LogicalUnitNumber = DeviceExtension->Lun;
+ TransferBlocks = (USHORT)(CurrentIrpStack->Parameters.Read.Length >> DeviceExtension->SectorShift);
- Cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
- Cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
- Cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
- Cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
+ /* Copy little endian values into CDB in big endian format */
+ Cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte3;
+ Cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte2;
+ Cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte1;
+ Cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte0;
- Cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
- Cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
+ Cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&TransferBlocks)->Byte1;
+ Cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&TransferBlocks)->Byte0;
- //
- // Set transfer direction flag and Cdb command.
- //
- if (currentIrpStack->MajorFunction == IRP_MJ_READ)
+ if (CurrentIrpStack->MajorFunction == IRP_MJ_READ)
{
- DPRINT1("ScsiClassBuildRequest: Read Command\n");
+ DPRINT("ScsiClassBuildRequest: Read Command\n");
- Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
- Cdb->CDB10.OperationCode = SCSIOP_READ;
+ Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
+ Cdb->CDB10.OperationCode = SCSIOP_READ;
}
else
{
- DPRINT("ScsiClassBuildRequest: Write Command\n");
+ DPRINT("ScsiClassBuildRequest: Write Command\n");
- Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
- Cdb->CDB10.OperationCode = SCSIOP_WRITE;
+ Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
+ Cdb->CDB10.OperationCode = SCSIOP_WRITE;
}
- //
- // If this is not a write-through request, then allow caching.
- //
#if 0
- if (!(currentIrpStack->Flags & SL_WRITE_THROUGH))
+ /* if this is not a write-through request, then allow caching */
+ if (!(CurrentIrpStack->Flags & SL_WRITE_THROUGH))
{
- Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
+ Srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
}
else
{
- /* If write caching is enable then force media access in the cdb. */
- if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE)
+ /* if write caching is enable then force media access in the cdb */
+ if (DeviceExtension->DeviceFlags & DEV_WRITE_CACHE)
{
Cdb->CDB10.ForceUnitAccess = TRUE;
}
}
#endif
- /* Or in the default flags from the device object. */
- Srb->SrbFlags |= deviceExtension->SrbFlags;
-
- //
- // Set up major SCSI function.
- //
+ /* or in the default flags from the device object. */
+ Srb->SrbFlags |= DeviceExtension->SrbFlags;
- nextIrpStack->MajorFunction = IRP_MJ_SCSI;
- //
- // Save SRB address in next stack for port driver.
- //
+ NextIrpStack->MajorFunction = IRP_MJ_SCSI;
+ NextIrpStack->Parameters.Scsi.Srb = Srb;
+ NextIrpStack->DeviceObject = DeviceObject;
- nextIrpStack->Parameters.Scsi.Srb = Srb;
-
- //
- // Save retry count in current IRP stack.
- //
#if 0
- currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
+ /* save retry count in current IRP stack */
+ CurrentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
#endif
- /* Set up IoCompletion routine address. */
+ DPRINT("IoSetCompletionRoutine (Irp %p Srb %p)\n", Irp, Srb);
IoSetCompletionRoutine(Irp,
ScsiClassIoComplete,
Srb,
PIRP Irp;
NTSTATUS Status;
- DPRINT1("ScsiClassClaimDevice() called\n");
+ DPRINT("ScsiClassClaimDevice() called\n");
if (NewPortDeviceObject != NULL)
*NewPortDeviceObject = NULL;
- /* Initialize an SRB */
+ /* initialize an SRB */
RtlZeroMemory(&Srb,
sizeof(SCSI_REQUEST_BLOCK));
Srb.Length = SCSI_REQUEST_BLOCK_SIZE;
UNICODE_STRING DeviceName;
NTSTATUS Status;
- DPRINT1("ScsiClassCreateDeviceObject() called\n");
+ DPRINT("ScsiClassCreateDeviceObject() called\n");
*DeviceObject = NULL;
return(Status);
}
- DPRINT1("Device name: '%wZ'\n", &DeviceName);
+ DPRINT("Device name: '%wZ'\n", &DeviceName);
Status = IoCreateDevice(DriverObject,
InitializationData->DeviceExtensionSize,
&InternalDeviceObject);
if (NT_SUCCESS(Status))
{
- PDEVICE_EXTENSION deviceExtension = InternalDeviceObject->DeviceExtension;
+ DeviceExtension = InternalDeviceObject->DeviceExtension;
DeviceExtension->ClassError = InitializationData->ClassError;
DeviceExtension->ClassReadWriteVerification = InitializationData->ClassReadWriteVerification;
KEVENT Event;
PIRP Irp;
+ DPRINT1("ScsiClassGetInquiryData() called\n");
+
*ConfigInfo = NULL;
Buffer = ExAllocatePool(NonPagedPool,
INQUIRY_DATA_SIZE);
*ConfigInfo = Buffer;
}
+ DPRINT1("ScsiClassGetInquiryData() done\n");
+
return(Status);
}
ConfigInfo = IoGetConfigurationInformation();
+ DPRINT("ScsiPorts: %lu\n", ConfigInfo->ScsiPortCount);
+
/* look for ScsiPortX scsi port devices */
for (PortNumber = 0; PortNumber < ConfigInfo->ScsiPortCount; PortNumber++)
{
DPRINT("Status 0x%08lX\n", Status);
if (NT_SUCCESS(Status))
{
- DPRINT1("ScsiPort%lu found.\n", PortNumber);
+ DPRINT("ScsiPort%lu found.\n", PortNumber);
- /* Check scsi port for attached disk drives */
+ /* check scsi port for attached disk drives */
if (InitializationData->ClassFindDevices(DriverObject,
Argument2,
InitializationData,
DiskFound = TRUE;
}
}
+ else
+ {
+ DbgPrint("Couldn't find ScsiPort%lu (Status %lx)\n", PortNumber, Status);
+ }
}
DPRINT("ScsiClassInitialize() done!\n");
-for(;;);
return((DiskFound == TRUE) ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE);
}
PIRP Irp,
PVOID Context)
{
- DPRINT1("ScsiClassIoComplete() called\n");
+ PDEVICE_EXTENSION DeviceExtension;
+ PIO_STACK_LOCATION IrpStack;
+ PSCSI_REQUEST_BLOCK Srb;
+ NTSTATUS Status;
+
+ DPRINT("ScsiClassIoComplete(DeviceObject %p Irp %p Context %p) called\n",
+ DeviceObject, Irp, Context);
+
+ DeviceExtension = DeviceObject->DeviceExtension;
+ Srb = (PSCSI_REQUEST_BLOCK)Context;
+ DPRINT("Srb %p\n", Srb);
+
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+#if 0
+ if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS)
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* FIXME: improve error handling */
+ DPRINT1("Srb->SrbStatus %lx\n", Srb->SrbStatus);
+
+ if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_PENDING)
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ Status = STATUS_UNSUCCESSFUL;
+ }
+#endif
+
+ /* FIXME: use lookaside list instead */
+ DPRINT("Freed SRB %p\n", IrpStack->Parameters.Scsi.Srb);
+ ExFreePool(IrpStack->Parameters.Scsi.Srb);
+
+// Irp->IoStatus.Status = Status;
+#if 0
+ if (!NT_SUCCESS(Status) &&
+ IoIsErrorUserInduced(Status))
+ {
+ IoSetHardErrorOrVerifyDevice(Irp,
+ DeviceObject);
+ Irp->IoStatus.Information = 0;
+ }
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
+#endif
- return(Irp->IoStatus.Status);
+ if (DeviceExtension->ClassStartIo != NULL)
+ {
+ if (IrpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL)
+ {
+ IoStartNextPacket(DeviceObject,
+ FALSE);
+ }
+ }
+
+ DPRINT("ScsiClassIoComplete() done (Status %lx)\n", Status);
+
+// return(Status);
+ return(STATUS_SUCCESS);
}
ULONG LastSector;
ULONG SectorSize;
- DPRINT1("ScsiClassReadDriveCapacity() called\n");
+ DPRINT("ScsiClassReadDriveCapacity() called\n");
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
DeviceExtension->DiskGeometry->BytesPerSector = SectorSize;
DeviceExtension->PartitionLength.QuadPart = (LONGLONG)(LastSector + 1);
- WHICH_BIT(DeviceExtension->DiskGeometry->BytesPerSector, DeviceExtension->SectorShift);
+ WHICH_BIT(DeviceExtension->DiskGeometry->BytesPerSector,
+ DeviceExtension->SectorShift);
DeviceExtension->PartitionLength.QuadPart =
(DeviceExtension->PartitionLength.QuadPart << DeviceExtension->SectorShift);
DeviceExtension->DiskGeometry->SectorsPerTrack = 32;
DeviceExtension->DiskGeometry->TracksPerCylinder = 64;
- DPRINT1("SectorSize: %lu SectorCount: %lu\n", SectorSize, LastSector + 1);
+ DPRINT("SectorSize: %lu SectorCount: %lu\n", SectorSize, LastSector + 1);
}
ExFreePool(CapacityBuffer);
- DPRINT1("ScsiClassReadDriveCapacity() done\n");
+ DPRINT("ScsiClassReadDriveCapacity() done\n");
return(Status);
}
NTSTATUS Status;
- DPRINT1("ScsiClassSendSrbSynchronous() called\n");
+ DPRINT("ScsiClassSendSrbSynchronous() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
&IoStatusBlock);
if (Irp == NULL)
{
- DPRINT("IoBuildDeviceIoControlRequest() failed\n");
+ DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS)
{
-
+ /* FIXME!! */
+ DPRINT1("Fix return value!\n");
+ Status = STATUS_UNSUCCESSFUL;
}
else
{
Status = STATUS_SUCCESS;
}
- DPRINT1("ScsiClassSendSrbSynchronous() done\n");
+ DPRINT("ScsiClassSendSrbSynchronous() done\n");
return(Status);
}
ULONG TransferPages;
NTSTATUS Status;
- DPRINT1("ScsiClassReadWrite() called\n");
+ DPRINT("ScsiClassReadWrite() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ DPRINT("Relative Offset: %I64u Length: %lu\n",
+ IrpStack->Parameters.Read.ByteOffset.QuadPart,
+ IrpStack->Parameters.Read.Length);
+
TransferLength = IrpStack->Parameters.Read.Length;
if (DeviceExtension->ClassStartIo != NULL)
{
+ DPRINT("ScsiClassReadWrite() starting packet\n");
+
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject,
Irp,
ScsiClassBuildRequest(DeviceObject,
Irp);
- DPRINT1("ScsiClassReadWrite() done\n");
+ DPRINT("ScsiClassReadWrite() done\n");
/* Call the port driver */
return(IoCallDriver(DeviceExtension->PortDeviceObject,
ScsiClassDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- DPRINT1("ScsiClassDeviceDispatch() called\n");
+ PDEVICE_EXTENSION DeviceExtension;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
+ DPRINT("ScsiClassDeviceDispatch() called\n");
+
+ DeviceExtension = DeviceObject->DeviceExtension;
+ if (DeviceExtension->ClassDeviceControl)
+ {
+ return(DeviceExtension->ClassDeviceControl(DeviceObject, Irp));
+ }
+
+ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return(STATUS_SUCCESS);
+ return(STATUS_INVALID_DEVICE_REQUEST);
}
ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- DPRINT1("ScsiClassShutdownFlush() called\n");
+ PDEVICE_EXTENSION DeviceExtension;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
+ DPRINT("ScsiClassShutdownFlush() called\n");
+
+ DeviceExtension = DeviceObject->DeviceExtension;
+ if (DeviceExtension->ClassShutdownFlush)
+ {
+ return(DeviceExtension->ClassShutdownFlush(DeviceObject, Irp));
+ }
+
+ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return(STATUS_SUCCESS);
+ return(STATUS_INVALID_DEVICE_REQUEST);
}
/* EOF */