scsiport.c
来自「一个类似windows」· C语言 代码 · 共 2,184 行 · 第 1/5 页
C
2,184 行
LunExtension = SpiGetLunExtension(DeviceExtension,
PathId,
TargetId,
Lun);
if (LunExtension)
{
DeviceExtension->Flags |= IRP_FLAG_NEXT_LU;
LunExtension->Flags |= IRP_FLAG_NEXT_LU;
}
}
break;
case ResetDetected:
DPRINT1("Notify: ResetDetected\n");
/* FIXME: ??? */
break;
default:
DPRINT1 ("Unsupported notification %lu\n", NotificationType);
break;
}
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
IoRequestDpc(DeviceExtension->DeviceObject,
NULL,
DeviceExtension);
}
else
{
SpiProcessRequests(DeviceExtension, NULL);
}
va_end(ap);
}
/*
* @implemented
*/
ULONG STDCALL
ScsiPortSetBusDataByOffset(IN PVOID DeviceExtension,
IN ULONG BusDataType,
IN ULONG SystemIoBusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
DPRINT("ScsiPortSetBusDataByOffset()\n");
return(HalSetBusDataByOffset(BusDataType,
SystemIoBusNumber,
SlotNumber,
Buffer,
Offset,
Length));
}
/*
* @implemented
*/
BOOLEAN STDCALL
ScsiPortValidateRange(IN PVOID HwDeviceExtension,
IN INTERFACE_TYPE BusType,
IN ULONG SystemIoBusNumber,
IN SCSI_PHYSICAL_ADDRESS IoAddress,
IN ULONG NumberOfBytes,
IN BOOLEAN InIoSpace)
{
DPRINT("ScsiPortValidateRange()\n");
return(TRUE);
}
/* INTERNAL FUNCTIONS ********************************************************/
static BOOLEAN
SpiGetPciConfigData (IN struct _HW_INITIALIZATION_DATA *HwInitializationData,
IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig,
IN ULONG BusNumber,
IN OUT PPCI_SLOT_NUMBER NextSlotNumber)
{
PCI_COMMON_CONFIG PciConfig;
PCI_SLOT_NUMBER SlotNumber;
ULONG DataSize;
ULONG DeviceNumber;
ULONG FunctionNumber;
CHAR VendorIdString[8];
CHAR DeviceIdString[8];
ULONG i;
ULONG RangeLength;
DPRINT ("SpiGetPciConfiguration() called\n");
if (NextSlotNumber->u.bits.FunctionNumber >= PCI_MAX_FUNCTION)
{
NextSlotNumber->u.bits.FunctionNumber = 0;
NextSlotNumber->u.bits.DeviceNumber++;
}
if (NextSlotNumber->u.bits.DeviceNumber >= PCI_MAX_DEVICES)
{
NextSlotNumber->u.bits.DeviceNumber = 0;
return FALSE;
}
for (DeviceNumber = NextSlotNumber->u.bits.DeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
{
SlotNumber.u.bits.DeviceNumber = DeviceNumber;
for (FunctionNumber = NextSlotNumber->u.bits.FunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
{
SlotNumber.u.bits.FunctionNumber = FunctionNumber;
DataSize = HalGetBusData (PCIConfiguration,
BusNumber,
SlotNumber.u.AsULONG,
&PciConfig,
PCI_COMMON_HDR_LENGTH);
if (DataSize != PCI_COMMON_HDR_LENGTH)
{
if (FunctionNumber == 0)
{
break;
}
else
{
continue;
}
}
sprintf (VendorIdString, "%04hx", PciConfig.VendorID);
sprintf (DeviceIdString, "%04hx", PciConfig.DeviceID);
if (!_strnicmp(VendorIdString, HwInitializationData->VendorId, HwInitializationData->VendorIdLength) &&
!_strnicmp(DeviceIdString, HwInitializationData->DeviceId, HwInitializationData->DeviceIdLength))
{
DPRINT ("Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
PciConfig.VendorID,
PciConfig.DeviceID,
BusNumber,
SlotNumber.u.bits.DeviceNumber,
SlotNumber.u.bits.FunctionNumber);
PortConfig->BusInterruptLevel =
PortConfig->BusInterruptVector = PciConfig.u.type0.InterruptLine;
PortConfig->SlotNumber = SlotNumber.u.AsULONG;
/* Initialize access ranges */
if (PortConfig->NumberOfAccessRanges > 0)
{
if (PortConfig->NumberOfAccessRanges > PCI_TYPE0_ADDRESSES)
PortConfig->NumberOfAccessRanges = PCI_TYPE0_ADDRESSES;
for (i = 0; i < PortConfig->NumberOfAccessRanges; i++)
{
(*PortConfig->AccessRanges)[i].RangeStart.QuadPart =
PciConfig.u.type0.BaseAddresses[i] & PCI_ADDRESS_IO_ADDRESS_MASK;
if ((*PortConfig->AccessRanges)[i].RangeStart.QuadPart != 0)
{
RangeLength = (ULONG)-1;
HalSetBusDataByOffset (PCIConfiguration,
BusNumber,
SlotNumber.u.AsULONG,
(PVOID)&RangeLength,
0x10 + (i * sizeof(ULONG)),
sizeof(ULONG));
HalGetBusDataByOffset (PCIConfiguration,
BusNumber,
SlotNumber.u.AsULONG,
(PVOID)&RangeLength,
0x10 + (i * sizeof(ULONG)),
sizeof(ULONG));
HalSetBusDataByOffset (PCIConfiguration,
BusNumber,
SlotNumber.u.AsULONG,
(PVOID)&PciConfig.u.type0.BaseAddresses[i],
0x10 + (i * sizeof(ULONG)),
sizeof(ULONG));
if (RangeLength != 0)
{
(*PortConfig->AccessRanges)[i].RangeLength =
-(RangeLength & PCI_ADDRESS_IO_ADDRESS_MASK);
(*PortConfig->AccessRanges)[i].RangeInMemory =
!(PciConfig.u.type0.BaseAddresses[i] & PCI_ADDRESS_IO_SPACE);
DPRINT("RangeStart 0x%lX RangeLength 0x%lX RangeInMemory %s\n",
PciConfig.u.type0.BaseAddresses[i] & PCI_ADDRESS_IO_ADDRESS_MASK,
-(RangeLength & PCI_ADDRESS_IO_ADDRESS_MASK),
(PciConfig.u.type0.BaseAddresses[i] & PCI_ADDRESS_IO_SPACE)?"FALSE":"TRUE");
}
}
}
}
NextSlotNumber->u.bits.DeviceNumber = DeviceNumber;
NextSlotNumber->u.bits.FunctionNumber = FunctionNumber;
PortConfig->SlotNumber = NextSlotNumber->u.AsULONG;
NextSlotNumber->u.bits.FunctionNumber += 1;
return TRUE;
}
if (FunctionNumber == 0 && !(PciConfig.HeaderType & PCI_MULTIFUNCTION))
{
break;
}
}
NextSlotNumber->u.bits.FunctionNumber = 0;
}
DPRINT ("No device found\n");
return FALSE;
}
/**********************************************************************
* NAME INTERNAL
* ScsiPortCreateClose
*
* DESCRIPTION
* Answer requests for Create/Close calls: a null operation.
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* DeviceObject
* Pointer to a device object.
*
* Irp
* Pointer to an IRP.
*
* RETURN VALUE
* Status.
*/
static NTSTATUS STDCALL
ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("ScsiPortCreateClose()\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
/**********************************************************************
* 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)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PSCSI_PORT_LUN_EXTENSION LunExtension;
PIO_STACK_LOCATION Stack;
PSCSI_REQUEST_BLOCK Srb;
NTSTATUS Status = STATUS_SUCCESS;
ULONG DataSize = 0;
DPRINT("ScsiPortDispatchScsi(DeviceObject %p Irp %p)\n",
DeviceObject, Irp);
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
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);
DPRINT("PathId: %lu TargetId: %lu Lun: %lu\n", Srb->PathId, Srb->TargetId, Srb->Lun);
LunExtension = SpiGetLunExtension(DeviceExtension,
Srb->PathId,
Srb->TargetId,
Srb->Lun);
if (LunExtension == NULL)
{
Status = STATUS_NO_SUCH_DEVICE;
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
switch (Srb->Function)
{
case SRB_FUNCTION_EXECUTE_SCSI:
case SRB_FUNCTION_IO_CONTROL:
IoMarkIrpPending(Irp);
Srb->OriginalRequest = LunExtension;
Irp->Tail.Overlay.DriverContext[3] = Srb;
SpiProcessRequests(DeviceExtension, Irp);
return(STATUS_PENDING);
case SRB_FUNCTION_SHUTDOWN:
case SRB_FUNCTION_FLUSH:
if (DeviceExtension->PortConfig->CachesData == TRUE)
{
IoMarkIrpPending(Irp);
Srb->OriginalRequest = LunExtension;
Irp->Tail.Overlay.DriverContext[3] = Srb;
SpiProcessRequests(DeviceExtension, Irp);
return(STATUS_PENDING);
}
break;
case SRB_FUNCTION_CLAIM_DEVICE:
DPRINT (" SRB_FUNCTION_CLAIM_DEVICE\n");
/* Reference device object and keep the device object */
ObReferenceObject(DeviceObject);
LunExtension->DeviceObject = DeviceObject;
LunExtension->DeviceClaimed = TRUE;
Srb->DataBuffer = DeviceObject;
break;
case SRB_FUNCTION_RELEASE_DEVICE:
DPRINT (" SRB_FUNCTION_RELEASE_DEVICE\n");
DPRINT ("PathId: %lu TargetId: %lu Lun: %lu\n",
Srb->PathId, Srb->TargetId, Srb->Lun);
/* Dereference device object and clear the device object */
ObDereferenceObject(LunExtension->DeviceObject);
LunExtension->DeviceObject = NULL;
LunExtension->DeviceClaimed = FALSE;
break;
default:
DPRINT1("SRB function not implemented (Function %lu)\n", Srb->Function);
Status = STATUS_NOT_IMPLEMENTED;
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;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ScsiPortDeviceControl()\n");
Irp->IoStatus.Information = 0;
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = DeviceObject->DeviceExtension;
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SCSI_GET_DUMP_POINTERS:
{
PDUMP_POINTERS DumpPointers;
DPRINT(" IOCTL_SCSI_GET_DUMP_POINTERS\n");
DumpPointers = (PDUMP_POINTERS)Irp->AssociatedIrp.SystemBuffer;
DumpPointers->DeviceObject = DeviceObject;
Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
}
break;
case IOCTL_SCSI_GET_CAPABILITIES:
{
DPRINT(" IOCTL_SCSI_GET_CAPABILITIES\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?