Disk driver stack update.

svn path=/trunk/; revision=2583
This commit is contained in:
Eric Kohl 2002-01-31 14:58:52 +00:00
parent 760f3874ca
commit ae35748cfa
8 changed files with 2181 additions and 1707 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,41 +0,0 @@
/**
*** Partition.h - defines and structs for harddrive partition info
***
*** 05/30/98 RJJ Created
**/
#ifndef __PARTITION_H
#define __PARTITION_H
#define PARTITION_MAGIC 0xaa55
#define PART_MAGIC_OFFSET 0x01fe
#define PARTITION_OFFSET 0x01be
#define PARTITION_TBL_SIZE 4
#define PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \
(scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2)))
#define PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \
(s) = (lba) % (scnt) + 1, \
(lba) /= (scnt), \
(h) = (lba) % (hcnt), \
(lba) /= (heads), \
(c) = (lba) & 0xff, \
(s) |= ((lba) >> 2) & 0xc0)
typedef struct Partition {
unsigned char BootFlags;
unsigned char StartingHead;
unsigned char StartingSector;
unsigned char StartingCylinder;
unsigned char PartitionType;
unsigned char EndingHead;
unsigned char EndingSector;
unsigned char EndingCylinder;
unsigned int StartingBlock;
unsigned int SectorCount;
} PARTITION;
#endif // PARTITION_H

View file

@ -1,4 +1,4 @@
/* $Id: class2.c,v 1.3 2002/01/27 01:25:01 ekohl Exp $
/* $Id: class2.c,v 1.4 2002/01/31 14:57:58 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -9,8 +9,7 @@
/*
* TODO:
* - ScsiClassClaimDevice() must send a claim/unclaim request to
* scsiport.sys.
* - a lot ;-)
*/
/* INCLUDES *****************************************************************/
@ -111,7 +110,199 @@ VOID STDCALL
ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED;
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;
PSCSI_REQUEST_BLOCK Srb;
PCDB Cdb;
ULONG logicalBlockAddress;
USHORT transferBlocks;
//
// Calculate relative sector address.
//
// logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
startingBlock.QuadPart = startingOffset.QuadPart >> deviceExtension->SectorShift;
logicalBlockAddress = (ULONG)startingBlock.u.LowPart;
//
// Allocate an Srb.
//
// Srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
Srb = ExAllocatePool(NonPagedPool,
sizeof(SCSI_REQUEST_BLOCK));
Srb->SrbFlags = 0;
//
// Write length to SRB.
//
Srb->Length = sizeof(SCSI_REQUEST_BLOCK); //SCSI_REQUEST_BLOCK_SIZE;
//
// 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;
//
// Fill in CDB fields.
//
Cdb = (PCDB)Srb->Cdb;
//
// Zero 12 bytes for Atapi Packets
//
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.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;
//
// Set transfer direction flag and Cdb command.
//
if (currentIrpStack->MajorFunction == IRP_MJ_READ)
{
DPRINT1("ScsiClassBuildRequest: Read Command\n");
Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
Cdb->CDB10.OperationCode = SCSIOP_READ;
}
else
{
DPRINT("ScsiClassBuildRequest: Write Command\n");
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))
{
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)
{
Cdb->CDB10.ForceUnitAccess = TRUE;
}
}
#endif
/* Or in the default flags from the device object. */
Srb->SrbFlags |= deviceExtension->SrbFlags;
//
// Set up major SCSI function.
//
nextIrpStack->MajorFunction = IRP_MJ_SCSI;
//
// Save SRB address in next stack for port driver.
//
nextIrpStack->Parameters.Scsi.Srb = Srb;
//
// Save retry count in current IRP stack.
//
#if 0
currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
#endif
/* Set up IoCompletion routine address. */
IoSetCompletionRoutine(Irp,
ScsiClassIoComplete,
Srb,
TRUE,
TRUE,
TRUE);
}
@ -121,6 +312,11 @@ ScsiClassClaimDevice(PDEVICE_OBJECT PortDeviceObject,
BOOLEAN Release,
PDEVICE_OBJECT *NewPortDeviceObject OPTIONAL)
{
PIO_STACK_LOCATION IoStack;
IO_STATUS_BLOCK IoStatusBlock;
SCSI_REQUEST_BLOCK Srb;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
DPRINT1("ScsiClassClaimDevice() called\n");
@ -128,19 +324,70 @@ ScsiClassClaimDevice(PDEVICE_OBJECT PortDeviceObject,
if (NewPortDeviceObject != NULL)
*NewPortDeviceObject = NULL;
/* Initialize an SRB */
RtlZeroMemory(&Srb,
sizeof(SCSI_REQUEST_BLOCK));
Srb.Length = SCSI_REQUEST_BLOCK_SIZE;
Srb.PathId = LunInfo->PathId;
Srb.TargetId = LunInfo->TargetId;
Srb.Lun = LunInfo->Lun;
Srb.Function =
(Release == TRUE) ? SRB_FUNCTION_RELEASE_DEVICE : SRB_FUNCTION_CLAIM_DEVICE;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_EXECUTE_NONE,
PortDeviceObject,
NULL,
0,
NULL,
0,
TRUE,
&Event,
&IoStatusBlock);
if (Irp == NULL)
{
DPRINT1("Failed to allocate Irp!\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Link Srb and Irp */
IoStack = IoGetNextIrpStackLocation(Irp);
IoStack->Parameters.Scsi.Srb = &Srb;
Srb.OriginalRequest = Irp;
/* Call SCSI port driver */
Status = IoCallDriver(PortDeviceObject,
Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event,
Suspended,
KernelMode,
FALSE,
NULL);
Status = IoStatusBlock.Status;
}
if (Release == TRUE)
{
ObDereferenceObject(PortDeviceObject);
return(STATUS_SUCCESS);
}
ObReferenceObjectByPointer(PortDeviceObject,
0,
NULL,
KernelMode);
// Status = ObReferenceObjectByPointer(Srb.DataBuffer,
Status = ObReferenceObjectByPointer(PortDeviceObject,
0,
NULL,
KernelMode);
if (NewPortDeviceObject != NULL)
*NewPortDeviceObject = PortDeviceObject;
{
// *NewPortDeviceObject = Srb.DataBuffer;
*NewPortDeviceObject = PortDeviceObject;
}
return(STATUS_SUCCESS);
}
@ -153,20 +400,65 @@ ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
IN OUT PDEVICE_OBJECT *DeviceObject,
IN PCLASS_INIT_DATA InitializationData)
{
PDEVICE_OBJECT InternalDeviceObject;
PDEVICE_EXTENSION DeviceExtension;
ANSI_STRING AnsiName;
UNICODE_STRING DeviceName;
NTSTATUS Status;
DPRINT1("ScsiClassCreateDeviceObject() called\n");
#if 0
*DeviceObject = NULL;
RtlInitAnsiString(&AnsiName,
ObjectNameBuffer);
Status = RtlAnsiStringToUnicodeString(&DeviceName,
&AnsiName,
TRUE);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DPRINT1("Device name: '%wZ'\n", &DeviceName);
Status = IoCreateDevice(DriverObject,
InitializationData->DeviceExtensionSize,
&UnicodeName,
&DeviceName,
InitializationData->DeviceType,
InitializationData->DeviceCharacteristics,
FALSE,
&InternalDeviceObject);
#endif
if (NT_SUCCESS(Status))
{
PDEVICE_EXTENSION deviceExtension = InternalDeviceObject->DeviceExtension;
DeviceExtension->ClassError = InitializationData->ClassError;
DeviceExtension->ClassReadWriteVerification = InitializationData->ClassReadWriteVerification;
DeviceExtension->ClassFindDevices = InitializationData->ClassFindDevices;
DeviceExtension->ClassDeviceControl = InitializationData->ClassDeviceControl;
DeviceExtension->ClassShutdownFlush = InitializationData->ClassShutdownFlush;
DeviceExtension->ClassCreateClose = InitializationData->ClassCreateClose;
DeviceExtension->ClassStartIo = InitializationData->ClassStartIo;
return(STATUS_SUCCESS);
DeviceExtension->MediaChangeCount = 0;
if (PhysicalDeviceObject != NULL)
{
DeviceExtension->PhysicalDevice = PhysicalDeviceObject;
}
else
{
DeviceExtension->PhysicalDevice = InternalDeviceObject;
}
*DeviceObject = InternalDeviceObject;
}
RtlFreeUnicodeString(&DeviceName);
return(Status);
}
@ -458,7 +750,14 @@ ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
UNIMPLEMENTED;
DPRINT1("ScsiClassIoComplete() called\n");
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
return(Irp->IoStatus.Status);
}
@ -491,7 +790,81 @@ ScsiClassQueryTimeOutRegistryValue(IN PUNICODE_STRING RegistryPath)
NTSTATUS STDCALL
ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
PDEVICE_EXTENSION DeviceExtension;
PREAD_CAPACITY_DATA CapacityBuffer;
SCSI_REQUEST_BLOCK Srb;
PCDB Cdb;
NTSTATUS Status;
ULONG LastSector;
ULONG SectorSize;
DPRINT1("ScsiClassReadDriveCapacity() called\n");
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
CapacityBuffer = ExAllocatePool(NonPagedPool, //NonPagedPoolCacheAligned,
sizeof(READ_CAPACITY_DATA));
if (CapacityBuffer == NULL)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
Srb.CdbLength = 10;
Srb.TimeOutValue = DeviceExtension->TimeOutValue;
Cdb = (PCDB)Srb.Cdb;
Cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
Status = ScsiClassSendSrbSynchronous(DeviceObject,
&Srb,
CapacityBuffer,
sizeof(READ_CAPACITY_DATA),
FALSE);
DPRINT("Status: %lx\n", Status);
DPRINT("Srb: %p\n", &Srb);
if (NT_SUCCESS(Status))
{
SectorSize = (((PUCHAR)&CapacityBuffer->BytesPerBlock)[0] << 24) |
(((PUCHAR)&CapacityBuffer->BytesPerBlock)[1] << 16) |
(((PUCHAR)&CapacityBuffer->BytesPerBlock)[2] << 8) |
((PUCHAR)&CapacityBuffer->BytesPerBlock)[3];
LastSector = (((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[0] << 24) |
(((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[1] << 16) |
(((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[2] << 8) |
((PUCHAR)&CapacityBuffer->LogicalBlockAddress)[3];
DeviceExtension->DiskGeometry->BytesPerSector = SectorSize;
DeviceExtension->PartitionLength.QuadPart = (LONGLONG)(LastSector + 1);
WHICH_BIT(DeviceExtension->DiskGeometry->BytesPerSector, DeviceExtension->SectorShift);
DeviceExtension->PartitionLength.QuadPart =
(DeviceExtension->PartitionLength.QuadPart << DeviceExtension->SectorShift);
if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
{
DeviceExtension->DiskGeometry->MediaType = RemovableMedia;
}
else
{
DeviceExtension->DiskGeometry->MediaType = FixedMedia;
}
DeviceExtension->DiskGeometry->Cylinders.QuadPart = (LONGLONG)((LastSector + 1)/(32 * 64));
DeviceExtension->DiskGeometry->SectorsPerTrack = 32;
DeviceExtension->DiskGeometry->TracksPerCylinder = 64;
DPRINT1("SectorSize: %lu SectorCount: %lu\n", SectorSize, LastSector + 1);
}
ExFreePool(CapacityBuffer);
DPRINT1("ScsiClassReadDriveCapacity() done\n");
return(Status);
}
@ -521,7 +894,103 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
ULONG BufferLength,
BOOLEAN WriteToDevice)
{
UNIMPLEMENTED;
PDEVICE_EXTENSION DeviceExtension;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION IoStack;
ULONG RequestType;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
DPRINT1("ScsiClassSendSrbSynchronous() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
Srb->PathId = DeviceExtension->PathId;
Srb->TargetId = DeviceExtension->TargetId;
Srb->Lun = DeviceExtension->Lun;
Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
/* FIXME: more srb initialization required? */
if (BufferAddress == NULL)
{
BufferLength = 0;
RequestType = IOCTL_SCSI_EXECUTE_NONE;
Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
}
else
{
if (WriteToDevice == TRUE)
{
RequestType = IOCTL_SCSI_EXECUTE_OUT;
Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
}
else
{
RequestType = IOCTL_SCSI_EXECUTE_IN;
Srb->SrbFlags = SRB_FLAGS_DATA_IN;
}
}
Srb->DataTransferLength = BufferLength;
Srb->DataBuffer = BufferAddress;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
Irp = IoBuildDeviceIoControlRequest(RequestType,
DeviceExtension->PortDeviceObject,
NULL,
0,
BufferAddress,
BufferLength,
TRUE,
&Event,
&IoStatusBlock);
if (Irp == NULL)
{
DPRINT("IoBuildDeviceIoControlRequest() failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* FIXME: more irp initialization required? */
/* Attach Srb to the Irp */
IoStack = IoGetNextIrpStackLocation(Irp);
IoStack->Parameters.Scsi.Srb = Srb;
Srb->OriginalRequest = Irp;
/* Call the SCSI port driver */
Status = IoCallDriver(DeviceExtension->PortDeviceObject,
Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event,
Suspended,
KernelMode,
FALSE,
NULL);
}
if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS)
{
}
else
{
Status = STATUS_SUCCESS;
}
DPRINT1("ScsiClassSendSrbSynchronous() done\n");
return(Status);
}
@ -540,10 +1009,15 @@ static NTSTATUS STDCALL
ScsiClassCreateClose(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
// PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PDEVICE_EXTENSION DeviceExtension;
// if (deviceExtension->ClassCreateClose)
// return(deviceExtension->ClassCreateClose(DeviceObject, Irp));
DPRINT("ScsiClassCreateClose() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
if (DeviceExtension->ClassCreateClose)
return(DeviceExtension->ClassCreateClose(DeviceObject,
Irp));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
@ -557,11 +1031,98 @@ static NTSTATUS STDCALL
ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpStack;
ULONG TransferLength;
ULONG TransferPages;
NTSTATUS Status;
return(STATUS_SUCCESS);
DPRINT1("ScsiClassReadWrite() called\n");
DeviceExtension = DeviceObject->DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
TransferLength = IrpStack->Parameters.Read.Length;
if ((DeviceObject->Flags & DO_VERIFY_VOLUME) &&
!(IrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME))
{
IoSetHardErrorOrVerifyDevice(Irp,
DeviceObject);
Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_VERIFY_REQUIRED);
}
#if 0
/* let the class driver perform its verification */
Status = DeviceExtension->ClassReadWriteVerification(DeviceObject,
Irp);
if (!NT_SUCCESS(Status))
{
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(Status);
}
else if (Status == STATUS_PENDING)
{
IoMarkIrpPending(Irp);
return(STATUS_PENDING);
}
#endif
/* Finish a zero-byte transfer. */
if (TransferLength == 0)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
if (DeviceExtension->ClassStartIo != NULL)
{
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject,
Irp,
NULL,
NULL);
return(STATUS_PENDING);
}
IoMarkIrpPending(Irp);
/* Adjust partition-relative starting offset to absolute offset */
IrpStack->Parameters.Read.ByteOffset.QuadPart += DeviceExtension->StartingOffset.QuadPart;
/* Calculate number of pages in this transfer. */
TransferPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
IrpStack->Parameters.Read.Length);
#if 0
if (IrpStack->Parameters.Read.Length > maximumTransferLength ||
TransferPages > DeviceExtension->PortCapabilities->MaximumPhysicalPages)
{
}
#endif
ScsiClassBuildRequest(DeviceObject,
Irp);
DPRINT1("ScsiClassReadWrite() done\n");
/* Call the port driver */
return(IoCallDriver(DeviceExtension->PortDeviceObject,
Irp));
}
@ -569,6 +1130,8 @@ static NTSTATUS STDCALL
ScsiClassScsiDispatch(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("ScsiClassScsiDispatch() called\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -581,6 +1144,8 @@ static NTSTATUS STDCALL
ScsiClassDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("ScsiClassDeviceDispatch() called\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -593,6 +1158,8 @@ static NTSTATUS STDCALL
ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("ScsiClassShutdownFlush() called\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

View file

@ -1,4 +1,4 @@
/* $Id: disk.c,v 1.3 2002/01/27 01:25:15 ekohl Exp $
/* $Id: disk.c,v 1.4 2002/01/31 14:58:12 ekohl Exp $
*
*/
@ -33,6 +33,10 @@ DiskClassFindDevices(PDRIVER_OBJECT DriverObject,
BOOLEAN STDCALL
DiskClassCheckDevice(IN PINQUIRYDATA InquiryData);
NTSTATUS STDCALL
DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
static NTSTATUS
DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
@ -40,7 +44,7 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PortDeviceObject,
IN ULONG PortNumber,
IN ULONG DiskNumber,
IN PIO_SCSI_CAPABILITIES Capabilities, /* what's this used for? */
IN PIO_SCSI_CAPABILITIES Capabilities,
IN PSCSI_INQUIRY_DATA InquiryData,
IN PCLASS_INIT_DATA InitializationData);
@ -90,12 +94,12 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
sizeof(CLASS_INIT_DATA));
InitData.InitializationDataSize = sizeof(CLASS_INIT_DATA);
InitData.DeviceExtensionSize = sizeof(DISK_DEVICE_EXTENSION);
InitData.DeviceExtensionSize = sizeof(DEVICE_EXTENSION) + sizeof(DISK_DEVICE_EXTENSION);
InitData.DeviceType = FILE_DEVICE_DISK;
InitData.DeviceCharacteristics = 0;
InitData.ClassError = NULL; // DiskClassProcessError;
InitData.ClassReadWriteVerification = NULL; // DiskClassReadWriteCheck;
InitData.ClassReadWriteVerification = DiskClassCheckReadWrite;
InitData.ClassFindDeviceCallBack = DiskClassCheckDevice;
InitData.ClassFindDevices = DiskClassFindDevices;
InitData.ClassDeviceControl = DiskClassDeviceControl;
@ -275,8 +279,17 @@ DiskClassCheckDevice(IN PINQUIRYDATA InquiryData)
}
NTSTATUS STDCALL
DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("DiskClassCheckReadWrite() called\n");
// IDECreateDevices
return(STATUS_SUCCESS);
}
// DiskClassCreateDeviceObject
//
// DESCRIPTION:
// Create the raw device and any partition devices on this drive
@ -306,27 +319,26 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PortDeviceObject,
IN ULONG PortNumber,
IN ULONG DiskNumber,
IN PIO_SCSI_CAPABILITIES Capabilities, /* what's this used for? */
IN PIO_SCSI_CAPABILITIES Capabilities,
IN PSCSI_INQUIRY_DATA InquiryData,
IN PCLASS_INIT_DATA InitializationData) /* what's this used for? */
IN PCLASS_INIT_DATA InitializationData)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeDeviceDirName;
WCHAR NameBuffer[80];
CHAR NameBuffer2[80];
PDEVICE_OBJECT DiskDeviceObject;
PDEVICE_EXTENSION DiskDeviceExtension; /* defined in class2.h */
PDRIVE_LAYOUT_INFORMATION PartitionList = NULL;
HANDLE Handle;
#if 0
IDE_DRIVE_IDENTIFY DrvParms;
PIDE_DEVICE_EXTENSION DiskDeviceExtension;
PDEVICE_OBJECT PartitionDeviceObject;
PIDE_DEVICE_EXTENSION PartitionDeviceExtension;
ULONG SectorCount = 0;
PDRIVE_LAYOUT_INFORMATION PartitionList = NULL;
PPARTITION_INFORMATION PartitionEntry;
#endif
ULONG i;
PPARTITION_INFORMATION PartitionEntry;
ULONG PartitionNumber;
NTSTATUS Status;
DPRINT1("DiskClassCreateDeviceObjects() called\n");
@ -380,42 +392,138 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
{
DPRINT1("ScsiClassCreateDeviceObject() failed (Status %x)\n", Status);
/* Release (unclaim) the disk */
ScsiClassClaimDevice(PortDeviceObject,
InquiryData,
TRUE,
NULL);
/* Delete the harddisk device directory */
ZwMakeTemporaryObject(Handle);
ZwClose(Handle);
return(Status);
}
#if 0
/* Read partition table */
Status = IoReadPartitionTable(DiskDeviceObject,
DrvParms.BytesPerSector,
TRUE,
&PartitionList);
if (!NT_SUCCESS(Status))
DiskDeviceObject->Flags |= DO_DIRECT_IO;
if (((PINQUIRYDATA)InquiryData->InquiryData)->RemovableMedia)
{
DbgPrint("IoReadPartitionTable() failed\n");
return FALSE;
DiskDeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
}
DiskDeviceObject->StackSize = (CCHAR)PortDeviceObject->StackSize + 1;
if (PortDeviceObject->AlignmentRequirement > DiskDeviceObject->AlignmentRequirement)
{
DiskDeviceObject->AlignmentRequirement = PortDeviceObject->AlignmentRequirement;
}
DPRINT(" Number of partitions: %u\n", PartitionList->PartitionCount);
for (i=0;i < PartitionList->PartitionCount; i++)
DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
DiskDeviceExtension->LockCount = 0;
DiskDeviceExtension->DeviceNumber = DiskNumber;
DiskDeviceExtension->PortDeviceObject = PortDeviceObject;
/* FIXME: Not yet! Will cause pointer corruption! */
// DiskDeviceExtension->PortCapabilities = PortCapabilities;
DiskDeviceExtension->StartingOffset.QuadPart = 0;
DiskDeviceExtension->PortNumber = (UCHAR)PortNumber;
DiskDeviceExtension->PathId = InquiryData->PathId;
DiskDeviceExtension->TargetId = InquiryData->TargetId;
DiskDeviceExtension->Lun = InquiryData->Lun;
/* Get disk geometry */
DiskDeviceExtension->DiskGeometry = ExAllocatePool(NonPagedPool,
sizeof(DISK_GEOMETRY));
if (DiskDeviceExtension->DiskGeometry == NULL)
{
PartitionEntry = &PartitionList->PartitionEntry[i];
DPRINT1("Failed to allocate geometry buffer!\n");
DPRINT("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
i,
PartitionEntry->PartitionNumber,
PartitionEntry->BootIndicator,
PartitionEntry->PartitionType,
PartitionEntry->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
PartitionEntry->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
IoDeleteDevice(DiskDeviceObject);
/* Release (unclaim) the disk */
ScsiClassClaimDevice(PortDeviceObject,
InquiryData,
TRUE,
NULL);
/* Delete the harddisk device directory */
ZwMakeTemporaryObject(Handle);
ZwClose(Handle);
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Read the drive's capacity */
Status = ScsiClassReadDriveCapacity(DiskDeviceObject);
if (!NT_SUCCESS(Status) &&
(DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) == 0)
{
DPRINT1("Failed to retrieve drive capacity!\n");
return(STATUS_SUCCESS);
}
else
{
/* Clear the verify flag for non-removable media drives. */
DiskDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
}
DPRINT1("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector);
/* Read partition table */
Status = IoReadPartitionTable(DiskDeviceObject,
DiskDeviceExtension->DiskGeometry->BytesPerSector,
TRUE,
&PartitionList);
DPRINT1("IoReadPartitionTable(): Status: %lx\n", Status);
if ((!NT_SUCCESS(Status) || PartitionList->PartitionCount == 0) &&
DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
{
if (!NT_SUCCESS(Status))
{
/* Drive is not ready. */
// diskData->DriveNotReady = TRUE;
}
else
{
ExFreePool(PartitionList);
}
/* Allocate a partition list for a single entry. */
PartitionList = ExAllocatePool(NonPagedPool,
sizeof(DRIVE_LAYOUT_INFORMATION));
if (PartitionList != NULL)
{
RtlZeroMemory(PartitionList,
sizeof(DRIVE_LAYOUT_INFORMATION));
PartitionList->PartitionCount = 1;
Status = STATUS_SUCCESS;
}
}
if (NT_SUCCESS(Status))
{
DPRINT1("Read partition table!\n");
DPRINT(" Number of partitions: %u\n", PartitionList->PartitionCount);
for (PartitionNumber = 0; PartitionNumber < PartitionList->PartitionCount; PartitionNumber++)
{
PartitionEntry = &PartitionList->PartitionEntry[PartitionNumber];
DPRINT1("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
PartitionNumber,
PartitionEntry->PartitionNumber,
PartitionEntry->BootIndicator,
PartitionEntry->PartitionType,
PartitionEntry->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
PartitionEntry->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
#if 0
/* Create device for partition */
Status = IDECreateDevice(DriverObject,
&PartitionDeviceObject,
@ -432,14 +540,15 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
break;
}
/* Initialize pointer to disk device extension */
PartitionDeviceExtension = (PIDE_DEVICE_EXTENSION)PartitionDeviceObject->DeviceExtension;
PartitionDeviceExtension->DiskExtension = (PVOID)DiskDeviceExtension;
}
if (PartitionList != NULL)
ExFreePool(PartitionList);
/* Initialize pointer to disk device extension */
PartitionDeviceExtension = (PIDE_DEVICE_EXTENSION)PartitionDeviceObject->DeviceExtension;
PartitionDeviceExtension->DiskExtension = (PVOID)DiskDeviceExtension;
#endif
}
ExFreePool(PartitionList);
}
DPRINT1("DiskClassCreateDeviceObjects() done\n");

View file

@ -1,4 +1,4 @@
/* $Id: class2.h,v 1.2 2002/01/14 01:44:18 ekohl Exp $
/* $Id: class2.h,v 1.3 2002/01/31 14:58:34 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -151,7 +151,63 @@ ScsiClassInitialize(IN PVOID Argument1,
IN PVOID Argument2,
IN PCLASS_INIT_DATA InitializationData);
VOID STDCALL
ScsiClassInitializeSrbLookasideList(PDEVICE_EXTENSION DeviceExtension,
ULONG NumberElements);
NTSTATUS STDCALL
ScsiClassInternalIoControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
BOOLEAN STDCALL
ScsiClassInterpretSenseInfo(PDEVICE_OBJECT DeviceObject,
PSCSI_REQUEST_BLOCK Srb,
UCHAR MajorFunctionCode,
ULONG IoDeviceCode,
ULONG RetryCount,
NTSTATUS *Status);
NTSTATUS STDCALL
ScsiClassIoComplete(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context);
NTSTATUS STDCALL
ScsiClassIoCompleteAssociated(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context);
ULONG STDCALL
ScsiClassModeSense(PDEVICE_OBJECT DeviceObject,
CHAR ModeSenseBuffer,
ULONG Length,
UCHAR PageMode);
ULONG STDCALL
ScsiClassQueryTimeOutRegistryValue(IN PUNICODE_STRING RegistryPath);
NTSTATUS STDCALL
ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject);
NTSTATUS STDCALL
ScsiClassSendSrbAsynchronous(PDEVICE_OBJECT DeviceObject,
PSCSI_REQUEST_BLOCK Srb,
PIRP Irp,
PVOID BufferAddress,
ULONG BufferLength,
BOOLEAN WriteToDevice);
NTSTATUS STDCALL
ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject,
PSCSI_REQUEST_BLOCK Srb,
PVOID BufferAddress,
ULONG BufferLength,
BOOLEAN WriteToDevice);
VOID STDCALL
ScsiClassSplitRequest(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
ULONG MaximumBytes);
#endif /* __STORAGE_INCLUDE_CLASS2_H */

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id: srb.h,v 1.3 2002/01/27 01:25:34 ekohl Exp $
/* $Id: srb.h,v 1.4 2002/01/31 14:58:35 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -10,9 +10,8 @@
#ifndef __STORAGE_INCLUDE_SRB_H
#define __STORAGE_INCLUDE_SRB_H
//
// Define SCSI maximum configuration parameters.
//
/* Define SCSI maximum configuration parameters. */
#define SCSI_MAXIMUM_LOGICAL_UNITS 8
#define SCSI_MAXIMUM_TARGETS_PER_BUS 32
@ -20,14 +19,11 @@
#define SCSI_MINIMUM_PHYSICAL_BREAKS 16
#define SCSI_MAXIMUM_PHYSICAL_BREAKS 255
//
// This constant is for backward compatibility.
// This use to be the maximum number of targets supported.
//
/* Obsolete. For backward compatibility only. */
#define SCSI_MAXIMUM_TARGETS 8
// begin_ntminitape
#define MAXIMUM_CDB_SIZE 12
@ -125,9 +121,8 @@ typedef struct _SCSI_REQUEST_BLOCK
#define SCSI_REQUEST_BLOCK_SIZE sizeof(SCSI_REQUEST_BLOCK)
//
// SRB Functions
//
/* SRB Functions */
#define SRB_FUNCTION_EXECUTE_SCSI 0x00
#define SRB_FUNCTION_CLAIM_DEVICE 0x01
@ -146,9 +141,8 @@ typedef struct _SCSI_REQUEST_BLOCK
#define SRB_FUNCTION_FLUSH_QUEUE 0x15
#define SRB_FUNCTION_REMOVE_DEVICE 0x16
//
// SRB Status
//
/* SRB Status */
#define SRB_STATUS_PENDING 0x00
#define SRB_STATUS_SUCCESS 0x01
@ -177,18 +171,16 @@ typedef struct _SCSI_REQUEST_BLOCK
#define SRB_STATUS_BAD_FUNCTION 0x22
#define SRB_STATUS_ERROR_RECOVERY 0x23
//
// SRB Status Masks
//
/* SRB Status Masks */
#define SRB_STATUS_QUEUE_FROZEN 0x40
#define SRB_STATUS_AUTOSENSE_VALID 0x80
#define SRB_STATUS(Status) (Status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
//
// SRB Flag Bits
//
/* SRB Flag Bits */
#define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002
#define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004
@ -205,18 +197,15 @@ typedef struct _SCSI_REQUEST_BLOCK
#define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000
#define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000
//
// Queue Action
//
/* Queue Action */
#define SRB_SIMPLE_TAG_REQUEST 0x20
#define SRB_HEAD_OF_QUEUE_TAG_REQUEST 0x21
#define SRB_ORDERED_QUEUE_TAG_REQUEST 0x22
//
// Port driver error codes
//
/* Port driver error codes */
#define SP_BUS_PARITY_ERROR 0x0001
#define SP_UNEXPECTED_DISCONNECT 0x0002
@ -229,9 +218,8 @@ typedef struct _SCSI_REQUEST_BLOCK
#define SP_BAD_FW_WARNING 0x0009
#define SP_BAD_FW_ERROR 0x000a
//
// Return values for SCSI_HW_FIND_ADAPTER.
//
/* Return values for SCSI_HW_FIND_ADAPTER. */
#define SP_RETURN_NOT_FOUND 0
#define SP_RETURN_FOUND 1

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: scsiport.c,v 1.3 2002/01/27 01:25:49 ekohl Exp $
/* $Id: scsiport.c,v 1.4 2002/01/31 14:58:52 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -55,7 +55,13 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
ULONG MiniPortExtensionSize;
PORT_CONFIGURATION_INFORMATION PortConfig;
ULONG PortBusInfoSize;
PSCSI_ADAPTER_BUS_INFO PortBusInfo;
PCONTROLLER_OBJECT ControllerObject;
PHW_STARTIO HwStartIo;
PHW_INTERRUPT HwInterrupt;
UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
} SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION;
@ -126,10 +132,23 @@ static NTSTATUS STDCALL
ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
static NTSTATUS STDCALL
ScsiPortReadWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
static VOID STDCALL
ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
static IO_ALLOCATION_ACTION STDCALL
ScsiPortAllocateController(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID MapRegisterBase,
IN PVOID Context);
static BOOLEAN STDCALL
ScsiPortStartController(IN OUT PVOID Context);
static NTSTATUS
ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension,
@ -139,7 +158,7 @@ static BOOLEAN STDCALL
ScsiPortIsr(IN PKINTERRUPT Interrupt,
IN PVOID ServiceContext);
static VOID
static VOID STDCALL
ScsiPortDpcForIsr(IN PKDPC Dpc,
IN PDEVICE_OBJECT DpcDeviceObject,
IN PIRP DpcIrp,
@ -150,6 +169,7 @@ ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject,
PVOID Context);
/* FUNCTIONS *****************************************************************/
/**********************************************************************
@ -363,6 +383,33 @@ ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension,
}
/**********************************************************************
* NAME EXPORTED
* ScsiPortInitialize
*
* DESCRIPTION
* Initializes SCSI port driver specific data.
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* Argument1
* Pointer to the miniport driver's driver object.
*
* Argument2
* Pointer to the miniport driver's registry path.
*
* HwInitializationData
* Pointer to port driver specific configuration data.
*
* HwContext
Miniport driver specific context.
*
* RETURN VALUE
* Status.
*/
ULONG STDCALL
ScsiPortInitialize(IN PVOID Argument1,
IN PVOID Argument2,
@ -396,9 +443,9 @@ ScsiPortInitialize(IN PVOID Argument1,
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScsiPortCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScsiPortDeviceControl;
DriverObject->MajorFunction[IRP_MJ_SCSI] = ScsiPortDispatchScsi;
// DriverObject->MajorFunction[IRP_MJ_READ] = ScsiPortReadWrite;
// DriverObject->MajorFunction[IRP_MJ_WRITE] = ScsiPortReadWrite;
// DriverObject->MajorFunction[IRP_MJ_READ] = IDEDispatchReadWrite;
// DriverObject->MajorFunction[IRP_MJ_WRITE] = IDEDispatchReadWrite;
// DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = IDEDispatchQueryInformation;
// DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = IDEDispatchSetInformation;
@ -416,6 +463,7 @@ ScsiPortInitialize(IN PVOID Argument1,
PseudoDeviceExtension->Length = ExtensionSize;
PseudoDeviceExtension->MiniPortExtensionSize = HwInitializationData->DeviceExtensionSize;
PseudoDeviceExtension->HwStartIo = HwInitializationData->HwStartIo;
PseudoDeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
PortConfig = &PseudoDeviceExtension->PortConfig;
@ -616,68 +664,40 @@ ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject,
}
// ScsiPortDispatchScsi
//
// DESCRIPTION:
// Answer requests for SCSI calls
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// Standard dispatch arguments
//
// RETURNS:
// NTSTATUS
//
/**********************************************************************
* NAME INTERNAL
* ScsiPortDispatchScsi
*
* DESCRIPTION
* Answer requests for SCSI calls
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* Standard dispatch arguments
*
* RETURNS
* NTSTATUS
*/
static NTSTATUS STDCALL
ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("ScsiPortDispatchScsi()\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
// ScsiPortDeviceControl
//
// DESCRIPTION:
// Answer requests for device control calls
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// Standard dispatch arguments
//
// RETURNS:
// NTSTATUS
//
static NTSTATUS STDCALL
ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack;
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT("ScsiPortDeviceControl()\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
PIO_STACK_LOCATION Stack;
PSCSI_REQUEST_BLOCK Srb;
NTSTATUS Status = STATUS_SUCCESS;
ULONG DataSize = 0;
Stack = IoGetCurrentIrpStackLocation(Irp);
DPRINT1("ScsiPortDispatchScsi()\n");
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SCSI_EXECUTE_IN:
{
@ -696,6 +716,170 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
DPRINT1(" IOCTL_SCSI_EXECUTE_NONE\n");
}
break;
}
Srb = Stack->Parameters.Scsi.Srb;
if (Srb == NULL)
{
Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
DPRINT("Srb: %p\n", Srb);
DPRINT("Srb->Function: %lu\n", Srb->Function);
switch (Srb->Function)
{
case SRB_FUNCTION_EXECUTE_SCSI:
DPRINT1(" SRB_FUNCTION_EXECUTE_SCSI\n");
switch (Srb->Cdb[0])
{
case SCSIOP_INQUIRY:
case SCSIOP_READ_CAPACITY:
Status = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
Srb);
break;
default:
IoStartPacket(DeviceObject, Irp, NULL, NULL);
DPRINT1("Returning STATUS_PENDING\n");
return(STATUS_PENDING);
}
break;
case SRB_FUNCTION_CLAIM_DEVICE:
{
PSCSI_ADAPTER_BUS_INFO AdapterInfo;
PSCSI_INQUIRY_DATA UnitInfo;
PINQUIRYDATA InquiryData;
DPRINT(" SRB_FUNCTION_CLAIM_DEVICE\n");
if (DeviceExtension->PortBusInfo != NULL)
{
AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)DeviceExtension->PortBusInfo;
UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
AdapterInfo->BusData[Srb->PathId].InquiryDataOffset);
while (AdapterInfo->BusData[Srb->PathId].InquiryDataOffset)
{
InquiryData = (PINQUIRYDATA)UnitInfo->InquiryData;
if ((UnitInfo->TargetId == Srb->TargetId) &&
(UnitInfo->Lun == Srb->Lun) &&
(UnitInfo->DeviceClaimed == FALSE))
{
UnitInfo->DeviceClaimed = TRUE;
DPRINT("Claimed device!\n");
break;
}
if (UnitInfo->NextInquiryDataOffset == 0)
break;
UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + UnitInfo->NextInquiryDataOffset);
}
}
/* FIXME: Hack!!!!! */
Srb->DataBuffer = DeviceObject;
}
break;
case SRB_FUNCTION_RELEASE_DEVICE:
{
PSCSI_ADAPTER_BUS_INFO AdapterInfo;
PSCSI_INQUIRY_DATA UnitInfo;
PINQUIRYDATA InquiryData;
DPRINT(" SRB_FUNCTION_RELEASE_DEVICE\n");
if (DeviceExtension->PortBusInfo != NULL)
{
AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)DeviceExtension->PortBusInfo;
UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
AdapterInfo->BusData[Srb->PathId].InquiryDataOffset);
while (AdapterInfo->BusData[Srb->PathId].InquiryDataOffset)
{
InquiryData = (PINQUIRYDATA)UnitInfo->InquiryData;
if ((UnitInfo->TargetId == Srb->TargetId) &&
(UnitInfo->Lun == Srb->Lun) &&
(UnitInfo->DeviceClaimed == TRUE))
{
UnitInfo->DeviceClaimed = FALSE;
DPRINT("Released device!\n");
break;
}
if (UnitInfo->NextInquiryDataOffset == 0)
break;
UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + UnitInfo->NextInquiryDataOffset);
}
}
}
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = DataSize;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
/**********************************************************************
* NAME INTERNAL
* ScsiPortDeviceControl
*
* DESCRIPTION
* Answer requests for device control calls
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* Standard dispatch arguments
*
* RETURNS
* NTSTATUS
*/
static NTSTATUS STDCALL
ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack;
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT1("ScsiPortDeviceControl()\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = DeviceObject->DeviceExtension;
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SCSI_GET_CAPABILITIES:
{
@ -729,64 +913,85 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
ULONG Bus;
ULONG Target;
ULONG UnitCount;
ULONG DataSize;
BOOLEAN Result;
DPRINT1(" IOCTL_SCSI_GET_INQUIRY_DATA\n");
DPRINT(" IOCTL_SCSI_GET_INQUIRY_DATA\n");
AdapterInfo =(PSCSI_ADAPTER_BUS_INFO)Irp->AssociatedIrp.SystemBuffer;
AdapterInfo->NumberOfBuses = DeviceExtension->PortConfig.NumberOfBuses;
UnitInfo = (PSCSI_INQUIRY_DATA)
((PUCHAR)AdapterInfo + sizeof(SCSI_ADAPTER_BUS_INFO) +
(sizeof(SCSI_BUS_DATA) * (AdapterInfo->NumberOfBuses - 1)));
Srb.DataBuffer = ExAllocatePool(NonPagedPool, 256);
RtlZeroMemory(&Srb,
sizeof(SCSI_REQUEST_BLOCK));
Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
Srb.DataTransferLength = 256;
Srb.Cdb[0] = SCSIOP_INQUIRY;
for (Bus = 0; Bus < AdapterInfo->NumberOfBuses; Bus++)
/* Copy inquiry data to the port device extension */
if (DeviceExtension->PortBusInfo == NULL)
{
Srb.PathId = Bus;
AdapterInfo =(PSCSI_ADAPTER_BUS_INFO)Irp->AssociatedIrp.SystemBuffer;
AdapterInfo->NumberOfBuses = DeviceExtension->PortConfig.NumberOfBuses;
AdapterInfo->BusData[Bus].InitiatorBusId = 0; /* ? */
AdapterInfo->BusData[Bus].InquiryDataOffset =
(ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterInfo);
UnitInfo = (PSCSI_INQUIRY_DATA)
((PUCHAR)AdapterInfo + sizeof(SCSI_ADAPTER_BUS_INFO) +
(sizeof(SCSI_BUS_DATA) * (AdapterInfo->NumberOfBuses - 1)));
PrevUnit = NULL;
UnitCount = 0;
Srb.DataBuffer = ExAllocatePool(NonPagedPool, 256);
RtlZeroMemory(&Srb,
sizeof(SCSI_REQUEST_BLOCK));
Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
Srb.DataTransferLength = 256;
Srb.Cdb[0] = SCSIOP_INQUIRY;
for (Target = 0; Target < DeviceExtension->PortConfig.MaximumNumberOfTargets; Target++)
for (Bus = 0; Bus < AdapterInfo->NumberOfBuses; Bus++)
{
Srb.TargetId = Target;
Srb.Lun = 0;
Srb.PathId = Bus;
Result = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
&Srb);
if (Result == TRUE)
AdapterInfo->BusData[Bus].InitiatorBusId = 0; /* ? */
AdapterInfo->BusData[Bus].InquiryDataOffset =
(ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterInfo);
PrevUnit = NULL;
UnitCount = 0;
for (Target = 0; Target < DeviceExtension->PortConfig.MaximumNumberOfTargets; Target++)
{
UnitInfo->PathId = Bus;
UnitInfo->TargetId = Target;
UnitInfo->Lun = 0;
UnitInfo->InquiryDataLength = INQUIRYDATABUFFERSIZE;
memcpy(&UnitInfo->InquiryData,
Srb.DataBuffer,
INQUIRYDATABUFFERSIZE);
if (PrevUnit != NULL)
PrevUnit->NextInquiryDataOffset = (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterInfo);
PrevUnit = UnitInfo;
UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)UnitInfo + sizeof(SCSI_INQUIRY_DATA)+INQUIRYDATABUFFERSIZE-1);
UnitCount++;
Srb.TargetId = Target;
Srb.Lun = 0;
Result = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
&Srb);
if (Result == TRUE)
{
UnitInfo->PathId = Bus;
UnitInfo->TargetId = Target;
UnitInfo->Lun = 0;
UnitInfo->InquiryDataLength = INQUIRYDATABUFFERSIZE;
memcpy(&UnitInfo->InquiryData,
Srb.DataBuffer,
INQUIRYDATABUFFERSIZE);
if (PrevUnit != NULL)
PrevUnit->NextInquiryDataOffset = (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterInfo);
PrevUnit = UnitInfo;
UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)UnitInfo + sizeof(SCSI_INQUIRY_DATA)+INQUIRYDATABUFFERSIZE-1);
UnitCount++;
}
}
AdapterInfo->BusData[Bus].NumberOfLogicalUnits = UnitCount;
}
AdapterInfo->BusData[Bus].NumberOfLogicalUnits = UnitCount;
DataSize = (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterInfo);
ExFreePool(Srb.DataBuffer);
/* copy inquiry data to the port driver's device extension */
DeviceExtension->PortBusInfoSize = DataSize;
DeviceExtension->PortBusInfo = ExAllocatePool(NonPagedPool,
DataSize);
memcpy(DeviceExtension->PortBusInfo,
AdapterInfo,
DataSize);
}
else
{
memcpy(Irp->AssociatedIrp.SystemBuffer,
DeviceExtension->PortBusInfo,
DeviceExtension->PortBusInfoSize);
}
ExFreePool(Srb.DataBuffer);
DPRINT1("BufferSize: %lu\n",(ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterInfo));
Irp->IoStatus.Information = (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterInfo);
DPRINT("BufferSize: %lu\n", DeviceExtension->PortBusInfoSize);
Irp->IoStatus.Information = DeviceExtension->PortBusInfoSize;
}
break;
@ -802,36 +1007,172 @@ ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject,
}
static NTSTATUS STDCALL
ScsiPortReadWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
DPRINT1("ScsiPortReadWrite() called!\n");
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
static VOID STDCALL
ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpStack;
DPRINT("ScsiPortStartIo() called!\n");
KIRQL OldIrql;
DPRINT1("ScsiPortStartIo() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
// DeviceExtension = (PIDE_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
// FIXME: implement the supported functions
switch (IrpStack->MajorFunction)
{
case IRP_MJ_SCSI:
{
BOOLEAN Result;
PSCSI_REQUEST_BLOCK Srb;
DPRINT1("IRP_MJ_SCSI\n");
Srb = IrpStack->Parameters.Scsi.Srb;
// Result = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
// Srb);
/* FIXME: Needs error handling! */
// if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_EXECUTE_OUT)
// DataSize = Srb->DataTransferLength;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Srb->DataTransferLength;
IoMarkIrpPending(Irp);
CHECKPOINT1;
KeRaiseIrql(DISPATCH_LEVEL,
&OldIrql);
CHECKPOINT1;
IoAllocateController(DeviceExtension->ControllerObject,
DeviceObject,
ScsiPortAllocateController,
Irp);
CHECKPOINT1;
KeLowerIrql(OldIrql);
CHECKPOINT1;
#if 0
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Srb->DataTransferLength;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
IoStartNextPacket(DeviceObject,
FALSE);
#endif
}
break;
default:
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
// KeBugCheck((ULONG)Irp);
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
IoStartNextPacket(DeviceObject,
FALSE);
break;
}
DPRINT("ScsiPortStartIo() finished!\n");
DPRINT1("ScsiPortStartIo() done\n");
}
static IO_ALLOCATION_ACTION STDCALL
ScsiPortAllocateController(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID MapRegisterBase,
IN PVOID Context)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension;
DPRINT1("ScsiPortAllocateController() called\n");
DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)
DeviceExtension->ControllerObject->ControllerExtension;
ControllerExtension->CurrentIrp = Irp;
ControllerExtension->Retries = 0;
return(KeSynchronizeExecution(ControllerExtension->Interrupt,
ScsiPortStartController,
DeviceExtension) ? KeepObject :
DeallocateObject);
}
static BOOLEAN STDCALL
ScsiPortStartController(IN OUT PVOID Context)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension;
PIO_STACK_LOCATION IrpStack;
PSCSI_REQUEST_BLOCK Srb;
DPRINT1("ScsiPortStartController() called\n");
DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION) Context;
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)
DeviceExtension->ControllerObject->ControllerExtension;
ControllerExtension->OperationInProgress = TRUE;
ControllerExtension->DeviceForOperation = DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(ControllerExtension->CurrentIrp);
Srb = IrpStack->Parameters.Scsi.Srb;
return(DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
Srb));
}
/**********************************************************************
* NAME INTERNAL
* ScsiPortCreatePortDevice
*
* DESCRIPTION
* Creates and initializes a SCSI port device object.
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* DriverObject
* ...
*
* PseudoDeviceExtension
* ...
*
* PortNumber
* ...
*
* RETURNS
* NTSTATUS
*/
static NTSTATUS
ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension,
@ -848,12 +1189,15 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
NTSTATUS Status;
ULONG AccessRangeSize;
#if 0
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
#endif
DPRINT("ScsiPortCreatePortDevice() called\n");
#if 0
MappedIrq = HalGetInterruptVector(PseudoDeviceExtension->PortConfig.AdapterInterfaceType,
PseudoDeviceExtension->PortConfig.SystemIoBusNumber,
0,
@ -868,6 +1212,7 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
PortNumber);
return(STATUS_NO_SUCH_DEVICE);
}
#endif
/* Fill out Controller extension data */
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)
@ -886,12 +1231,12 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
ScsiPortIsr,
ControllerExtension,
&ControllerExtension->SpinLock,
MappedIrq,
Dirql,
Dirql,
PseudoDeviceExtension->PortConfig.BusInterruptVector, // MappedIrq,
PseudoDeviceExtension->PortConfig.BusInterruptLevel, // Dirql,
15, //Dirql,
PseudoDeviceExtension->PortConfig.InterruptMode,
FALSE,
Affinity,
0xFFFF, //Affinity,
FALSE);
if (!NT_SUCCESS(Status))
{
@ -933,6 +1278,7 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
PortDeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
PortDeviceExtension = PortDeviceObject->DeviceExtension;
PortDeviceExtension->ControllerObject = ControllerObject;
ControllerExtension->PortDeviceObject = PortDeviceObject;
@ -964,7 +1310,11 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
PseudoDeviceExtension->PortConfig.AccessRanges,
AccessRangeSize);
/* FIXME: Copy or configure any more? */
/* Initialize inquiry data */
PortDeviceExtension->PortBusInfoSize = 0;
PortDeviceExtension->PortBusInfo = NULL;
/* FIXME: Copy more configuration data? */
/* Create the dos device */
swprintf(DosNameBuffer,
@ -980,13 +1330,21 @@ ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
}
static BOOLEAN STDCALL
ScsiPortIsr(IN PKINTERRUPT Interrupt,
IN PVOID ServiceContext)
{
PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension;
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT1("ScsiPortIsr() called!\n");
ControllerExtension = (PSCSI_PORT_CONTROLLER_EXTENSION)ServiceContext;
DeviceExtension = ControllerExtension->DeviceForOperation;
return(TRUE);
}
@ -1002,7 +1360,7 @@ ScsiPortIsr(IN PKINTERRUPT Interrupt,
// IN PIRP DpcIrp
// IN PVOID DpcContext
//
static VOID
static VOID STDCALL
ScsiPortDpcForIsr(IN PKDPC Dpc,
IN PDEVICE_OBJECT DpcDeviceObject,
IN PIRP DpcIrp,