-/* $Id: class2.c,v 1.1 2001/07/23 06:12:07 ekohl Exp $
+/* $Id: class2.c,v 1.2 2002/01/14 01:43:26 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#include "../include/scsi.h"
#include "../include/class2.h"
+//#define NDEBUG
+#include <debug.h>
-#define UNIMPLEMENTED do {DbgPrint("%s:%d: Function not implemented", __FILE__, __LINE__); for(;;);} while (0)
+//#define UNIMPLEMENTED do {DbgPrint("%s:%d: Function not implemented", __FILE__, __LINE__); for(;;);} while (0)
#define VERSION "0.0.1"
+#define INQUIRY_DATA_SIZE 2048
+
+
+static NTSTATUS STDCALL
+ScsiClassCreateClose(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+static NTSTATUS STDCALL
+ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+static NTSTATUS STDCALL
+ScsiClassScsiDispatch(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+static NTSTATUS STDCALL
+ScsiClassDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+static NTSTATUS STDCALL
+ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
// ------------------------------------------------------- Public Interface
// DriverEntry
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
- DbgPrint("ScsiPort Driver %s\n", VERSION);
+ DbgPrint("Class Driver %s\n", VERSION);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
-ScsiClassAsynchronousCompletion(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PVOID Context)
+ScsiClassAsynchronousCompletion(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
{
UNIMPLEMENTED;
}
ScsiClassFindUnclaimedDevices(PCLASS_INIT_DATA InitializationData,
PSCSI_ADAPTER_BUS_INFO AdapterInformation)
{
- UNIMPLEMENTED;
+ DPRINT("ScsiClassFindUnclaimedDevices() called!\n");
+ return(0);
}
ScsiClassGetCapabilities(PDEVICE_OBJECT PortDeviceObject,
PIO_SCSI_CAPABILITIES *PortCapabilities)
{
- UNIMPLEMENTED;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+ KEVENT Event;
+ PIRP Irp;
+
+ KeInitializeEvent(&Event,
+ NotificationEvent,
+ FALSE);
+
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_GET_CAPABILITIES,
+ PortDeviceObject,
+ NULL,
+ 0,
+ PortCapabilities,
+ sizeof(PVOID),
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (Irp == NULL)
+ {
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ Status = IoCallDriver(PortDeviceObject,
+ Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL);
+ return(IoStatusBlock.Status);
+ }
+
+ return(Status);
}
ScsiClassGetInquiryData(PDEVICE_OBJECT PortDeviceObject,
PSCSI_ADAPTER_BUS_INFO *ConfigInfo)
{
- UNIMPLEMENTED;
+ PSCSI_ADAPTER_BUS_INFO Buffer;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+ KEVENT Event;
+ PIRP Irp;
+
+ Buffer = ExAllocatePool(NonPagedPool, /* FIXME: use paged pool */
+ INQUIRY_DATA_SIZE);
+ *ConfigInfo = Buffer;
+
+ if (Buffer == NULL)
+ {
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ KeInitializeEvent(&Event,
+ NotificationEvent,
+ FALSE);
+
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_GET_INQUIRY_DATA,
+ PortDeviceObject,
+ NULL,
+ 0,
+ Buffer,
+ INQUIRY_DATA_SIZE,
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (Irp == NULL)
+ {
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ Status = IoCallDriver(PortDeviceObject,
+ Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(Buffer);
+ *ConfigInfo = NULL;
+ }
+
+ return(Status);
}
PVOID Argument2,
PCLASS_INIT_DATA InitializationData)
{
- UNIMPLEMENTED;
+ PDRIVER_OBJECT DriverObject = Argument1;
+ WCHAR NameBuffer[80];
+ UNICODE_STRING PortName;
+ ULONG PortNumber = 0;
+ PDEVICE_OBJECT PortDeviceObject;
+ PFILE_OBJECT FileObject;
+ BOOLEAN DiskFound = FALSE;
+ NTSTATUS Status;
+
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = ScsiClassCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScsiClassCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_READ] = ScsiClassReadWrite;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = ScsiClassReadWrite;
+ DriverObject->MajorFunction[IRP_MJ_SCSI] = ScsiClassScsiDispatch;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScsiClassDeviceDispatch;
+ DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ScsiClassShutdownFlush;
+ DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ScsiClassShutdownFlush;
+ if (InitializationData->ClassStartIo)
+ {
+ DriverObject->DriverStartIo = InitializationData->ClassStartIo;
+ }
+
+ /* look for ScsiPortX scsi port devices */
+ do
+ {
+ swprintf(NameBuffer,
+ L"\\Device\\ScsiPort%lu",
+ PortNumber);
+ RtlInitUnicodeString(&PortName,
+ NameBuffer);
+ DPRINT1("Checking scsi port %ld\n", PortNumber);
+ Status = IoGetDeviceObjectPointer(&PortName,
+ FILE_READ_ATTRIBUTES,
+ &FileObject,
+ &PortDeviceObject);
+ DPRINT1("Status 0x%08lX\n", Status);
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT1("ScsiPort%lu found.\n", PortNumber);
+
+ /* Check scsi port for attached disk drives */
+ if (InitializationData->ClassFindDevices(DriverObject,
+ Argument2,
+ InitializationData,
+ PortDeviceObject,
+ PortNumber))
+ {
+ DiskFound = TRUE;
+ }
+
+ ObDereferenceObject(PortDeviceObject);
+ ObDereferenceObject(FileObject);
+ }
+ PortNumber++;
+ }
+ while (NT_SUCCESS(Status));
+
+for(;;);
+
+ return((DiskFound == TRUE) ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE);
}
ULONG STDCALL
-ScsiClassQueryTimeOutRegistryValue(PUNICODE_STRING RegistryPath)
+ScsiClassQueryTimeOutRegistryValue(IN PUNICODE_STRING RegistryPath)
{
UNIMPLEMENTED;
}
NTSTATUS STDCALL
-ScsiClassReadDriveCapacity(PDEVICE_OBJECT DeviceObject)
+ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
}
VOID STDCALL
-ScsiClassReleaseQueue(PDEVICE_OBJECT DeviceObject)
+ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
}
UNIMPLEMENTED;
}
+
+/* Internal Routines **************/
+
+static NTSTATUS STDCALL
+ScsiClassCreateClose(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(STATUS_SUCCESS);
+}
+
+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);
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS STDCALL
+ScsiClassScsiDispatch(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS STDCALL
+ScsiClassDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS STDCALL
+ScsiClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(STATUS_SUCCESS);
+}
+
/* EOF */