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 + -
显示快捷键?