3 * Copyright (C) 2001, 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: scsiport.c,v 1.3 2002/01/27 01:25:49 ekohl Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/storage/scsiport/scsiport.c
24 * PURPOSE: SCSI port driver
25 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
28 /* INCLUDES *****************************************************************/
30 #include <ddk/ntddk.h>
31 #include "../include/srb.h"
32 #include "../include/scsi.h"
33 #include "../include/ntddscsi.h"
39 #define VERSION "0.0.1"
42 /* TYPES *********************************************************************/
45 * SCSI_PORT_DEVICE_EXTENSION
48 * First part of the port objects device extension. The second
49 * part is the miniport-specific device extension.
52 typedef struct _SCSI_PORT_DEVICE_EXTENSION
55 ULONG MiniPortExtensionSize
;
56 PORT_CONFIGURATION_INFORMATION PortConfig
;
58 PHW_STARTIO HwStartIo
;
60 UCHAR MiniPortDeviceExtension
[1]; /* must be the last entry */
61 } SCSI_PORT_DEVICE_EXTENSION
, *PSCSI_PORT_DEVICE_EXTENSION
;
65 * SCSI_PORT_TIMER_STATES
68 * An enumeration containing the states in the timer DFA
71 typedef enum _SCSI_PORT_TIMER_STATES
75 IDETimerResetWaitForBusyNegate
,
76 IDETimerResetWaitForDrdyAssert
77 } SCSI_PORT_TIMER_STATES
;
81 * SCSI_PORT_CONTROLLER_EXTENSION
84 * Driver-defined structure used to hold miscellaneous controller information.
87 * Allocated from NON-PAGED POOL
88 * Available at any IRQL
91 typedef struct _SCSI_PORT_CONTROLLER_EXTENSION
97 BOOLEAN ControllerInterruptBug
;
98 PKINTERRUPT Interrupt
;
100 BOOLEAN OperationInProgress
;
102 PSCSI_PORT_DEVICE_EXTENSION DeviceForOperation
;
106 SCSI_PORT_TIMER_STATES TimerState
;
109 PDEVICE_OBJECT PortDeviceObject
;
111 } SCSI_PORT_CONTROLLER_EXTENSION
, *PSCSI_PORT_CONTROLLER_EXTENSION
;
114 /* GLOBALS *******************************************************************/
117 static NTSTATUS STDCALL
118 ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject
,
121 static NTSTATUS STDCALL
122 ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject
,
125 static NTSTATUS STDCALL
126 ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
130 ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject
,
134 ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject
,
135 IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension
,
138 static BOOLEAN STDCALL
139 ScsiPortIsr(IN PKINTERRUPT Interrupt
,
140 IN PVOID ServiceContext
);
143 ScsiPortDpcForIsr(IN PKDPC Dpc
,
144 IN PDEVICE_OBJECT DpcDeviceObject
,
146 IN PVOID DpcContext
);
149 ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject
,
153 /* FUNCTIONS *****************************************************************/
155 /**********************************************************************
160 * This function initializes the driver.
167 * System allocated Driver Object for this driver.
170 * Name of registry driver service key.
177 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
178 IN PUNICODE_STRING RegistryPath
)
180 DbgPrint("ScsiPort Driver %s\n", VERSION
);
181 return(STATUS_SUCCESS
);
185 /**********************************************************************
190 * Prints debugging messages.
197 * Debug level of the given message.
200 * Pointer to printf()-compatible format string.
203 Additional output data (see printf()).
210 ScsiDebugPrint(IN ULONG DebugPrintLevel
,
211 IN PCHAR DebugMessage
,
218 if (DebugPrintLevel
> InternalDebugLevel
)
222 va_start(ap
, DebugMessage
);
223 vsprintf(Buffer
, DebugMessage
, ap
);
231 ScsiPortCompleteRequest(IN PVOID HwDeviceExtension
,
242 ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address
)
244 return Address
.u
.LowPart
;
249 ScsiPortFlushDma(IN PVOID HwDeviceExtension
)
256 ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension
,
257 IN PVOID MappedAddress
)
264 ScsiPortGetBusData(IN PVOID DeviceExtension
,
265 IN ULONG BusDataType
,
266 IN ULONG SystemIoBusNumber
,
271 return(HalGetBusData(BusDataType
,
280 ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension
,
281 IN INTERFACE_TYPE BusType
,
282 IN ULONG SystemIoBusNumber
,
283 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
284 IN ULONG NumberOfBytes
,
285 IN BOOLEAN InIoSpace
)
288 PHYSICAL_ADDRESS TranslatedAddress
;
289 PVOID VirtualAddress
;
293 AddressSpace
= (ULONG
)InIoSpace
;
295 if (!HalTranslateBusAddress(BusType
,
303 if (AddressSpace
!= 0)
304 return (PVOID
)TranslatedAddress
.u
.LowPart
;
306 VirtualAddress
= MmMapIoSpace(TranslatedAddress
,
310 Buffer
= ExAllocatePool(NonPagedPool
,0x20);
312 return VirtualAddress
;
314 return NULL
; /* ?? */
319 ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension
,
328 SCSI_PHYSICAL_ADDRESS STDCALL
329 ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension
,
330 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
331 IN PVOID VirtualAddress
,
338 PSCSI_REQUEST_BLOCK STDCALL
339 ScsiPortGetSrb(IN PVOID DeviceExtension
,
350 ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension
,
351 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
352 IN ULONG NumberOfBytes
)
359 ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension
,
360 IN SCSI_PHYSICAL_ADDRESS PhysicalAddress
)
367 ScsiPortInitialize(IN PVOID Argument1
,
369 IN
struct _HW_INITIALIZATION_DATA
*HwInitializationData
,
372 PDRIVER_OBJECT DriverObject
= (PDRIVER_OBJECT
)Argument1
;
373 PUNICODE_STRING RegistryPath
= (PUNICODE_STRING
)Argument2
;
374 PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension
;
375 PCONFIGURATION_INFORMATION SystemConfig
;
376 PPORT_CONFIGURATION_INFORMATION PortConfig
;
382 PACCESS_RANGE AccessRanges
;
385 DPRINT1("ScsiPortInitialize() called!\n");
387 if ((HwInitializationData
->HwInitialize
== NULL
) ||
388 (HwInitializationData
->HwStartIo
== NULL
) ||
389 (HwInitializationData
->HwInterrupt
== NULL
) ||
390 (HwInitializationData
->HwFindAdapter
== NULL
) ||
391 (HwInitializationData
->HwResetBus
== NULL
))
392 return(STATUS_INVALID_PARAMETER
);
394 DriverObject
->DriverStartIo
= ScsiPortStartIo
;
395 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScsiPortCreateClose
;
396 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScsiPortCreateClose
;
397 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScsiPortDeviceControl
;
398 DriverObject
->MajorFunction
[IRP_MJ_SCSI
] = ScsiPortDispatchScsi
;
400 // DriverObject->MajorFunction[IRP_MJ_READ] = IDEDispatchReadWrite;
401 // DriverObject->MajorFunction[IRP_MJ_WRITE] = IDEDispatchReadWrite;
402 // DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = IDEDispatchQueryInformation;
403 // DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = IDEDispatchSetInformation;
408 SystemConfig
= IoGetConfigurationInformation();
410 ExtensionSize
= sizeof(SCSI_PORT_DEVICE_EXTENSION
) +
411 HwInitializationData
->DeviceExtensionSize
;
412 PseudoDeviceExtension
= ExAllocatePool(PagedPool
,
414 RtlZeroMemory(PseudoDeviceExtension
,
416 PseudoDeviceExtension
->Length
= ExtensionSize
;
417 PseudoDeviceExtension
->MiniPortExtensionSize
= HwInitializationData
->DeviceExtensionSize
;
418 PseudoDeviceExtension
->HwStartIo
= HwInitializationData
->HwStartIo
;
420 PortConfig
= &PseudoDeviceExtension
->PortConfig
;
422 PortConfig
->Length
= sizeof(PORT_CONFIGURATION_INFORMATION
);
423 PortConfig
->AdapterInterfaceType
= HwInitializationData
->AdapterInterfaceType
;
424 PortConfig
->InterruptMode
=
425 (PortConfig
->AdapterInterfaceType
== PCIBus
) ? LevelSensitive
: Latched
;
426 PortConfig
->AtdiskPrimaryClaimed
= SystemConfig
->AtDiskPrimaryAddressClaimed
;
427 PortConfig
->AtdiskSecondaryClaimed
= SystemConfig
->AtDiskSecondaryAddressClaimed
;
428 PortConfig
->NumberOfAccessRanges
= HwInitializationData
->NumberOfAccessRanges
;
430 PortConfig
->AccessRanges
=
431 ExAllocatePool(PagedPool
,
432 sizeof(ACCESS_RANGE
) * PortConfig
->NumberOfAccessRanges
);
435 PortConfig
->SystemIoBusNumber
= 0;
436 PortConfig
->SlotNumber
= 0;
438 MaxBus
= (PortConfig
->AdapterInterfaceType
== PCIBus
) ? 8 : 1;
440 DPRINT("MaxBus: %lu\n", MaxBus
);
444 DPRINT("Calling HwFindAdapter() for Bus %lu\n", PortConfig
->SystemIoBusNumber
);
446 // RtlZeroMemory(AccessRanges,
447 // sizeof(ACCESS_RANGE) * PortConfig->NumberOfAccessRanges);
449 /* Note: HwFindAdapter is called once for each bus */
450 Result
= (HwInitializationData
->HwFindAdapter
)(&PseudoDeviceExtension
->MiniPortDeviceExtension
,
452 NULL
, /* BusInformation */
453 NULL
, /* ArgumentString */
454 &PseudoDeviceExtension
->PortConfig
,
456 DPRINT("HwFindAdapter() result: %lu\n", Result
);
458 if (Result
== SP_RETURN_FOUND
)
460 DPRINT("ScsiPortInitialize(): Found HBA!\n");
462 Status
= ScsiPortCreatePortDevice(DriverObject
,
463 PseudoDeviceExtension
,
464 SystemConfig
->ScsiPortCount
);
466 if (!NT_SUCCESS(Status
))
468 DbgPrint("ScsiPortCreatePortDevice() failed! (Status 0x%lX)\n", Status
);
470 ExFreePool(PortConfig
->AccessRanges
);
471 ExFreePool(PseudoDeviceExtension
);
476 /* Update the configuration info */
477 SystemConfig
->AtDiskPrimaryAddressClaimed
= PortConfig
->AtdiskPrimaryClaimed
;
478 SystemConfig
->AtDiskSecondaryAddressClaimed
= PortConfig
->AtdiskSecondaryClaimed
;
479 SystemConfig
->ScsiPortCount
++;
484 PortConfig
->SystemIoBusNumber
++;
485 PortConfig
->SlotNumber
= 0;
488 DPRINT("Bus: %lu MaxBus: %lu\n", PortConfig
->SystemIoBusNumber
, MaxBus
);
489 if (PortConfig
->SystemIoBusNumber
>= MaxBus
)
491 DPRINT1("Scanned all buses!\n");
496 ExFreePool(PortConfig
->AccessRanges
);
497 ExFreePool(PseudoDeviceExtension
);
499 DPRINT1("ScsiPortInitialize() done!\n");
501 return(STATUS_SUCCESS
);
506 ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension
,
507 IN PSCSI_REQUEST_BLOCK Srb
,
508 IN ULONG LogicalAddress
,
516 ScsiPortLogError(IN PVOID HwDeviceExtension
,
517 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
529 ScsiPortMoveMemory(OUT PVOID Destination
,
533 RtlMoveMemory(Destination
,
540 ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType
,
541 IN PVOID HwDeviceExtension
,
549 ScsiPortSetBusDataByOffset(IN PVOID DeviceExtension
,
550 IN ULONG BusDataType
,
551 IN ULONG SystemIoBusNumber
,
557 return(HalSetBusDataByOffset(BusDataType
,
567 ScsiPortValidateRange(IN PVOID HwDeviceExtension
,
568 IN INTERFACE_TYPE BusType
,
569 IN ULONG SystemIoBusNumber
,
570 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
571 IN ULONG NumberOfBytes
,
572 IN BOOLEAN InIoSpace
)
578 /* INTERNAL FUNCTIONS ********************************************************/
580 /**********************************************************************
582 * ScsiPortCreateClose
585 * Answer requests for Create/Close calls: a null operation.
592 * Pointer to a device object.
598 Additional output data (see printf()).
604 static NTSTATUS STDCALL
605 ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject
,
608 DPRINT("ScsiPortCreateClose()\n");
610 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
611 Irp
->IoStatus
.Information
= FILE_OPENED
;
613 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
615 return(STATUS_SUCCESS
);
619 // ScsiPortDispatchScsi
622 // Answer requests for SCSI calls
628 // Standard dispatch arguments
634 static NTSTATUS STDCALL
635 ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject
,
638 DPRINT("ScsiPortDispatchScsi()\n");
640 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
641 Irp
->IoStatus
.Information
= 0;
643 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
645 return(STATUS_SUCCESS
);
649 // ScsiPortDeviceControl
652 // Answer requests for device control calls
658 // Standard dispatch arguments
664 static NTSTATUS STDCALL
665 ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
668 PIO_STACK_LOCATION Stack
;
669 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
671 DPRINT("ScsiPortDeviceControl()\n");
673 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
674 Irp
->IoStatus
.Information
= 0;
677 Stack
= IoGetCurrentIrpStackLocation(Irp
);
678 DeviceExtension
= DeviceObject
->DeviceExtension
;
680 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
682 case IOCTL_SCSI_EXECUTE_IN
:
684 DPRINT1(" IOCTL_SCSI_EXECUTE_IN\n");
688 case IOCTL_SCSI_EXECUTE_OUT
:
690 DPRINT1(" IOCTL_SCSI_EXECUTE_OUT\n");
694 case IOCTL_SCSI_EXECUTE_NONE
:
696 DPRINT1(" IOCTL_SCSI_EXECUTE_NONE\n");
700 case IOCTL_SCSI_GET_CAPABILITIES
:
702 PIO_SCSI_CAPABILITIES Capabilities
;
704 DPRINT1(" IOCTL_SCSI_GET_CAPABILITIES\n");
706 Capabilities
= (PIO_SCSI_CAPABILITIES
)Irp
->AssociatedIrp
.SystemBuffer
;
707 Capabilities
->Length
= sizeof(IO_SCSI_CAPABILITIES
);
708 Capabilities
->MaximumTransferLength
=
709 DeviceExtension
->PortConfig
.MaximumTransferLength
;
710 Capabilities
->MaximumPhysicalPages
= 1;
711 Capabilities
->SupportedAsynchronousEvents
= 0;
712 Capabilities
->AlignmentMask
=
713 DeviceExtension
->PortConfig
.AlignmentMask
;
714 Capabilities
->TaggedQueuing
=
715 DeviceExtension
->PortConfig
.TaggedQueuing
;
716 Capabilities
->AdapterScansDown
=
717 DeviceExtension
->PortConfig
.AdapterScansDown
;
718 Capabilities
->AdapterUsesPio
= TRUE
;
720 Irp
->IoStatus
.Information
= sizeof(IO_SCSI_CAPABILITIES
);
724 case IOCTL_SCSI_GET_INQUIRY_DATA
:
726 PSCSI_ADAPTER_BUS_INFO AdapterInfo
;
727 PSCSI_INQUIRY_DATA UnitInfo
, PrevUnit
;
728 SCSI_REQUEST_BLOCK Srb
;
734 DPRINT1(" IOCTL_SCSI_GET_INQUIRY_DATA\n");
736 AdapterInfo
=(PSCSI_ADAPTER_BUS_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
737 AdapterInfo
->NumberOfBuses
= DeviceExtension
->PortConfig
.NumberOfBuses
;
739 UnitInfo
= (PSCSI_INQUIRY_DATA
)
740 ((PUCHAR
)AdapterInfo
+ sizeof(SCSI_ADAPTER_BUS_INFO
) +
741 (sizeof(SCSI_BUS_DATA
) * (AdapterInfo
->NumberOfBuses
- 1)));
743 Srb
.DataBuffer
= ExAllocatePool(NonPagedPool
, 256);
745 sizeof(SCSI_REQUEST_BLOCK
));
746 Srb
.Function
= SRB_FUNCTION_EXECUTE_SCSI
;
747 Srb
.DataTransferLength
= 256;
748 Srb
.Cdb
[0] = SCSIOP_INQUIRY
;
750 for (Bus
= 0; Bus
< AdapterInfo
->NumberOfBuses
; Bus
++)
754 AdapterInfo
->BusData
[Bus
].InitiatorBusId
= 0; /* ? */
755 AdapterInfo
->BusData
[Bus
].InquiryDataOffset
=
756 (ULONG
)((PUCHAR
)UnitInfo
- (PUCHAR
)AdapterInfo
);
761 for (Target
= 0; Target
< DeviceExtension
->PortConfig
.MaximumNumberOfTargets
; Target
++)
763 Srb
.TargetId
= Target
;
766 Result
= DeviceExtension
->HwStartIo(&DeviceExtension
->MiniPortDeviceExtension
,
770 UnitInfo
->PathId
= Bus
;
771 UnitInfo
->TargetId
= Target
;
773 UnitInfo
->InquiryDataLength
= INQUIRYDATABUFFERSIZE
;
774 memcpy(&UnitInfo
->InquiryData
,
776 INQUIRYDATABUFFERSIZE
);
777 if (PrevUnit
!= NULL
)
778 PrevUnit
->NextInquiryDataOffset
= (ULONG
)((PUCHAR
)UnitInfo
-(PUCHAR
)AdapterInfo
);
780 UnitInfo
= (PSCSI_INQUIRY_DATA
)((PUCHAR
)UnitInfo
+ sizeof(SCSI_INQUIRY_DATA
)+INQUIRYDATABUFFERSIZE
-1);
784 AdapterInfo
->BusData
[Bus
].NumberOfLogicalUnits
= UnitCount
;
787 ExFreePool(Srb
.DataBuffer
);
788 DPRINT1("BufferSize: %lu\n",(ULONG
)((PUCHAR
)UnitInfo
-(PUCHAR
)AdapterInfo
));
789 Irp
->IoStatus
.Information
= (ULONG
)((PUCHAR
)UnitInfo
-(PUCHAR
)AdapterInfo
);
794 DPRINT1(" unknown ioctl code: 0x%lX\n",
795 Stack
->Parameters
.DeviceIoControl
.IoControlCode
);
799 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
801 return(STATUS_SUCCESS
);
806 ScsiPortStartIo(IN PDEVICE_OBJECT DeviceObject
,
809 PIO_STACK_LOCATION IrpStack
;
811 DPRINT("ScsiPortStartIo() called!\n");
813 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
814 // DeviceExtension = (PIDE_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
816 // FIXME: implement the supported functions
818 switch (IrpStack
->MajorFunction
)
822 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
823 Irp
->IoStatus
.Information
= 0;
824 // KeBugCheck((ULONG)Irp);
825 IoCompleteRequest(Irp
,
827 IoStartNextPacket(DeviceObject
,
831 DPRINT("ScsiPortStartIo() finished!\n");
836 ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject
,
837 IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension
,
840 PSCSI_PORT_CONTROLLER_EXTENSION ControllerExtension
;
841 PCONTROLLER_OBJECT ControllerObject
;
842 PSCSI_PORT_DEVICE_EXTENSION PortDeviceExtension
;
843 PDEVICE_OBJECT PortDeviceObject
;
844 WCHAR NameBuffer
[80];
845 UNICODE_STRING DeviceName
;
846 WCHAR DosNameBuffer
[80];
847 UNICODE_STRING DosDeviceName
;
849 ULONG AccessRangeSize
;
855 DPRINT("ScsiPortCreatePortDevice() called\n");
857 MappedIrq
= HalGetInterruptVector(PseudoDeviceExtension
->PortConfig
.AdapterInterfaceType
,
858 PseudoDeviceExtension
->PortConfig
.SystemIoBusNumber
,
860 PseudoDeviceExtension
->PortConfig
.BusInterruptLevel
,
864 ControllerObject
= IoCreateController(sizeof(SCSI_PORT_CONTROLLER_EXTENSION
));
865 if (ControllerObject
== NULL
)
867 DbgPrint("Could not create controller object for port %d\n",
869 return(STATUS_NO_SUCH_DEVICE
);
872 /* Fill out Controller extension data */
873 ControllerExtension
= (PSCSI_PORT_CONTROLLER_EXTENSION
)
874 ControllerObject
->ControllerExtension
;
875 ControllerExtension
->Number
= PortNumber
;
876 ControllerExtension
->Vector
= PseudoDeviceExtension
->PortConfig
.BusInterruptVector
;
877 ControllerExtension
->DMASupported
= FALSE
;
878 ControllerExtension
->ControllerInterruptBug
= FALSE
;
879 ControllerExtension
->OperationInProgress
= FALSE
;
881 /* Initialize the spin lock in the controller extension */
882 KeInitializeSpinLock(&ControllerExtension
->SpinLock
);
884 /* Register an interrupt handler for this controller */
885 Status
= IoConnectInterrupt(&ControllerExtension
->Interrupt
,
888 &ControllerExtension
->SpinLock
,
892 PseudoDeviceExtension
->PortConfig
.InterruptMode
,
896 if (!NT_SUCCESS(Status
))
898 DbgPrint("Could not Connect Interrupt %d\n",
899 ControllerExtension
->Vector
);
900 IoDeleteController (ControllerObject
);
904 /* Create a unicode device name */
906 L
"\\Device\\ScsiPort%lu",
908 RtlInitUnicodeString(&DeviceName
,
911 DPRINT("Creating device: %wZ\n", &DeviceName
);
913 /* Create the port device */
914 Status
= IoCreateDevice(DriverObject
,
915 PseudoDeviceExtension
->Length
,
917 FILE_DEVICE_CONTROLLER
,
921 if (!NT_SUCCESS(Status
))
923 DbgPrint("IoCreateDevice call failed! (Status 0x%lX)\n", Status
);
924 IoDisconnectInterrupt(ControllerExtension
->Interrupt
);
925 IoDeleteController(ControllerObject
);
929 DPRINT("Created device: %wZ\n", &DeviceName
);
931 /* Set the buffering strategy here... */
932 PortDeviceObject
->Flags
|= DO_DIRECT_IO
;
933 PortDeviceObject
->AlignmentRequirement
= FILE_WORD_ALIGNMENT
;
935 PortDeviceExtension
= PortDeviceObject
->DeviceExtension
;
937 ControllerExtension
->PortDeviceObject
= PortDeviceObject
;
939 /* Initialize the DPC object here */
940 IoInitializeDpcRequest(ControllerExtension
->PortDeviceObject
,
944 * Initialize the controller timer here
945 * (since it has to be tied to a device)
947 ControllerExtension
->TimerState
= IDETimerIdle
;
948 ControllerExtension
->TimerCount
= 0;
949 IoInitializeTimer(ControllerExtension
->PortDeviceObject
,
951 ControllerExtension
);
953 /* Copy port configuration in device extension */
954 memcpy(PortDeviceExtension
,
955 PseudoDeviceExtension
,
956 PseudoDeviceExtension
->Length
);
958 /* Copy access ranges */
960 sizeof(ACCESS_RANGE
) * PseudoDeviceExtension
->PortConfig
.NumberOfAccessRanges
;
961 PortDeviceExtension
->PortConfig
.AccessRanges
= ExAllocatePool(NonPagedPool
,
963 memcpy(PortDeviceExtension
->PortConfig
.AccessRanges
,
964 PseudoDeviceExtension
->PortConfig
.AccessRanges
,
967 /* FIXME: Copy or configure any more? */
969 /* Create the dos device */
970 swprintf(DosNameBuffer
,
973 RtlInitUnicodeString(&DosDeviceName
,
976 IoCreateSymbolicLink(&DosDeviceName
,
979 return(STATUS_SUCCESS
);
984 static BOOLEAN STDCALL
985 ScsiPortIsr(IN PKINTERRUPT Interrupt
,
986 IN PVOID ServiceContext
)
988 DPRINT1("ScsiPortIsr() called!\n");
1001 // IN PDEVICE_OBJECT DpcDeviceObject
1003 // IN PVOID DpcContext
1006 ScsiPortDpcForIsr(IN PKDPC Dpc
,
1007 IN PDEVICE_OBJECT DpcDeviceObject
,
1009 IN PVOID DpcContext
)
1011 DPRINT("ScsiPortDpcForIsr()\n");
1012 // IDEFinishOperation((PIDE_CONTROLLER_EXTENSION) DpcContext);
1018 // This function handles timeouts and other time delayed processing
1023 // IN PDEVICE_OBJECT DeviceObject Device object registered with timer
1024 // IN PVOID Context the Controller extension for the
1025 // controller the device is on
1028 ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject
,
1031 DPRINT("ScsiPortIoTimer()\n");