mirror of
https://github.com/reactos/reactos.git
synced 2024-08-16 16:39:08 +00:00
Disk driver stack update.
svn path=/trunk/; revision=2583
This commit is contained in:
parent
760f3874ca
commit
ae35748cfa
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue