1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=4:tabstop=4:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * winnt selftest driver framework
40 #define DEBUG_SUBSYSTEM S_LNET
47 #include <libcfs/libcfs.h>
50 /* libcfs module init/exit routines */
51 DECLARE_INIT(init_libcfs_module);
52 DECLARE_EXIT(exit_libcfs_module);
54 /* portal module init/exit routines */
55 DECLARE_INIT(init_lnet);
56 DECLARE_EXIT(fini_lnet);
58 /* tdinal module init/exit routines */
59 DECLARE_INIT(ksocknal_module_init);
60 DECLARE_EXIT(ksocknal_module_fini);
62 /* selftest module init/exit routines */
63 DECLARE_INIT(lnet_selftest_init);
64 DECLARE_EXIT(lnet_selftest_fini);
70 cfs_module_t libcfs_global_module = {"selftest"};
73 * structure definitions
76 #define LNET_SELFTEST_VERSION 0x00010001 /* LNET selftest module version */
78 #define LNET_SELFTEST_DEVICE L"\\Device\\Selftest" /* device object name */
79 #define LNET_SELFTEST_SYMLNK L"\\DosDevices\\Selftest" /* user-visible name for the device*/
81 typedef struct _DEVICE_EXTENSION {
83 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
89 PDEVICE_OBJECT SelfObject = NULL; /* lnet selftest object */
90 PDEVICE_OBJECT ProcObject = NULL; /* procfs emulator device */
99 // complete Irp request ...
109 Irp->IoStatus.Status = Status;
110 Irp->IoStatus.Information = Info;
111 IoCompleteRequest(Irp,IO_NO_INCREMENT);
117 // Open/Create Device ...
122 IN PDEVICE_OBJECT DeviceObject,
126 KdPrint(("LstCreate: DeviceCreate ...\n"));
128 return LstCompleteIrp(Irp,STATUS_SUCCESS,0);
137 IN PDEVICE_OBJECT DeviceObject,
140 KdPrint(("LstClose: Device Closed.\n"));
142 return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
144 UNREFERENCED_PARAMETER(DeviceObject);
149 // computer is being shut down
154 IN PDEVICE_OBJECT DeviceObject,
158 KdPrint(("LstShutdown: ...\n"));
160 return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
162 UNREFERENCED_PARAMETER(DeviceObject);
172 IN PDEVICE_OBJECT DeviceObject,
176 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
177 PIO_STACK_LOCATION IrpSp;
185 Irp->IoStatus.Information = 0;
186 IrpSp = IoGetCurrentIrpStackLocation(Irp);
188 ControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
189 InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
190 OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
191 lpvInBuffer = Irp->AssociatedIrp.SystemBuffer;
193 ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
197 case IOCTL_LIBCFS_VERSION:
199 *((ULONG *)lpvInBuffer) = (ULONG)(LNET_SELFTEST_VERSION);
200 Irp->IoStatus.Information = sizeof(ULONG);
201 Status = STATUS_SUCCESS;
208 Irp->IoStatus.Status = Status;
209 IoCompleteRequest(Irp, IO_NO_INCREMENT);
216 IN PDEVICE_OBJECT DeviceObject,
221 PIO_STACK_LOCATION IrpSp;
223 FILE_FULL_EA_INFORMATION * ea;
226 IrpSp = IoGetCurrentIrpStackLocation(Irp);
227 ea = (PFILE_FULL_EA_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
230 Status = STATUS_INVALID_PARAMETER;
232 fp = lustre_open_file(&ea->EaName[0]);
234 Status = STATUS_OBJECT_NAME_NOT_FOUND;
236 IrpSp->FileObject->FsContext = fp;
237 IrpSp->FileObject->FsContext2 = fp->private_data;
238 Status = STATUS_SUCCESS;
242 return LstCompleteIrp(Irp, Status, 0);
251 IN PDEVICE_OBJECT DeviceObject,
254 PIO_STACK_LOCATION IrpSp;
258 IrpSp = IoGetCurrentIrpStackLocation(Irp);
259 fp = (cfs_file_t *) IrpSp->FileObject->FsContext;
261 ASSERT(IrpSp->FileObject->FsContext2 == fp->private_data);
263 lustre_close_file(fp);
265 return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
267 UNREFERENCED_PARAMETER(DeviceObject);
271 * proc frame routines
276 IN PDEVICE_OBJECT DeviceObject,
280 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
281 PIO_STACK_LOCATION IrpSp;
289 Irp->IoStatus.Information = 0;
290 IrpSp = IoGetCurrentIrpStackLocation(Irp);
292 ControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
293 InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
294 OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
295 lpvInBuffer = Irp->AssociatedIrp.SystemBuffer;
297 ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
301 case IOCTL_LIBCFS_VERSION:
303 *((ULONG *)lpvInBuffer) = (ULONG)(LNET_SELFTEST_VERSION);
304 Irp->IoStatus.Information = sizeof(ULONG);
306 Status = STATUS_SUCCESS;
310 case IOCTL_LIBCFS_ENTRY:
315 fp = (cfs_file_t *) IrpSp->FileObject->FsContext;
320 rc = lustre_ioctl_file(fp, (PCFS_PROC_IOCTL) lpvInBuffer);
323 ((PCFS_PROC_IOCTL) lpvInBuffer)->rc = rc;
324 Irp->IoStatus.Information = InputLength;
325 Status = STATUS_SUCCESS;
329 Irp->IoStatus.Status = Status;
330 IoCompleteRequest(Irp, IO_NO_INCREMENT);
337 ProcReadWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
339 PIO_STACK_LOCATION IrpSp;
346 IrpSp = IoGetCurrentIrpStackLocation(Irp);
347 if (Irp->MdlAddress) {
348 buf = MmGetSystemAddressForMdlSafe(
352 buf = Irp->AssociatedIrp.SystemBuffer;
356 Status = STATUS_SUCCESS;
359 fp = (cfs_file_t *) IrpSp->FileObject->FsContext;
362 Status = STATUS_INVALID_PARAMETER;
366 if (IrpSp->MajorFunction == IRP_MJ_READ) {
367 rc = lustre_read_file(
368 fp, IrpSp->Parameters.Read.ByteOffset.LowPart,
369 IrpSp->Parameters.Read.Length, buf);
371 rc = lustre_write_file(
372 fp, IrpSp->Parameters.Write.ByteOffset.LowPart,
373 IrpSp->Parameters.Write.Length, buf);
376 cfs_enter_debugger();
377 Status = STATUS_UNSUCCESSFUL;
379 Status = STATUS_SUCCESS;
385 return LstCompleteIrp(Irp, Status, rc);
390 // common dispatch routines
395 IN PDEVICE_OBJECT DeviceObject,
400 PIO_STACK_LOCATION IrpSp;
402 Status = STATUS_INVALID_DEVICE_REQUEST;
406 IrpSp = IoGetCurrentIrpStackLocation(Irp);
408 switch (IrpSp->MajorFunction) {
411 if (DeviceObject == SelfObject) {
412 Status = LstCreate(DeviceObject, Irp);
413 } else if (DeviceObject == ProcObject) {
414 Status = ProcCreate(DeviceObject, Irp);
419 if (DeviceObject == SelfObject) {
420 Status = LstClose(DeviceObject, Irp);
421 } else if (DeviceObject == ProcObject) {
422 Status = ProcClose(DeviceObject, Irp);
428 if (DeviceObject == ProcObject) {
429 Status = ProcReadWrite(DeviceObject, Irp);
433 case IRP_MJ_DEVICE_CONTROL:
434 if (DeviceObject == SelfObject) {
435 Status = LstDeviceControl(DeviceObject, Irp);
436 } else if (DeviceObject == ProcObject) {
437 Status = ProcDeviceControl(DeviceObject, Irp);
441 case IRP_MJ_SHUTDOWN:
442 Status = LstShutdown(DeviceObject, Irp);
447 KdPrint(("LstDispatchRequest: Major Function: %xh is not supported.\n",
448 IrpSp->MajorFunction));
449 LstCompleteIrp(Irp, Status, 0);
461 // create a device object and a dosdevice symbol link
466 IN PDRIVER_OBJECT DriverObject,
467 IN PWCHAR DeviceName,
468 IN PWCHAR SymlnkName,
474 UNICODE_STRING NtDevName;
475 UNICODE_STRING Win32DevName;
477 PDEVICE_EXTENSION DeviceExtension;
478 PDEVICE_OBJECT DeviceObject;
480 /* create the device object with the specified name */
482 RtlInitUnicodeString(&NtDevName, DeviceName);
484 Status = IoCreateDevice(
486 sizeof(DEVICE_EXTENSION),
493 if (!NT_SUCCESS(Status)) {
495 cfs_enter_debugger();
499 /* create the symlink to make the device visible to user */
501 RtlInitUnicodeString(&Win32DevName, SymlnkName);
502 Status = IoCreateSymbolicLink(&Win32DevName, &NtDevName);
504 if (!NT_SUCCESS(Status)) {
506 IoDeleteDevice(DeviceObject);
510 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceObjectExtension;
511 DeviceExtension->bProcFS = bProcFS;
513 DeviceObject->AlignmentRequirement = 0;
514 DeviceObject->SectorSize = 0;
515 DeviceObject->Flags |= DO_BUFFERED_IO;
516 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
525 NTSTATUS DriverEntry(
526 IN PDRIVER_OBJECT DriverObject,
527 IN PUNICODE_STRING RegistryPath
530 KdPrint(("LNet selftest: Build Time: " __DATE__ " " __TIME__ "\n"));
531 KdPrint(("LNet selftest: DriverEntry ... \n"));
533 /* initialize libcfs module */
534 if (module_init_libcfs_module() != 0) {
535 KdPrint(("selftest: failed to initialize module: libcfs ...\n"));
539 /* initialize portals module */
540 if (module_init_lnet() != 0) {
541 KdPrint(("selftest: failed to initialize module: lnet ...\n"));
542 module_exit_libcfs_module();
546 /* initialize tdinal module */
547 if (module_ksocknal_module_init() != 0) {
548 KdPrint(("selftest: failed to initialize module: socklnd ...\n"));
550 module_exit_libcfs_module();
554 /* initialize lnet selttest module */
555 if (module_lnet_selftest_init() != 0) {
556 KdPrint(("selftest: failed to initialize module: selftest ...\n"));
557 module_ksocknal_module_fini();
559 module_exit_libcfs_module();
563 /* create lnet selftest device object */
564 SelfObject = LstCreateDevice(
566 LNET_SELFTEST_DEVICE,
567 LNET_SELFTEST_SYMLNK,
570 KdPrint(("selftest: failed to allocate DeviceObject ...\n"));
571 module_lnet_selftest_fini();
572 module_ksocknal_module_fini();
574 module_exit_libcfs_module();
576 return STATUS_INSUFFICIENT_RESOURCES;
579 /* create the libcfs proc fs emultor device object */
580 ProcObject = LstCreateDevice(
587 KdPrint(("selftest: failed to allocate proc DeviceObject ...\n"));
588 /* remove Selftest DeviceObject */
589 IoDeleteDevice(SelfObject);
590 module_lnet_selftest_fini();
591 module_ksocknal_module_fini();
593 module_exit_libcfs_module();
594 return STATUS_INSUFFICIENT_RESOURCES;
597 /* initialize the driver callback routines */
599 DriverObject->MajorFunction[IRP_MJ_CREATE] = LstDispatchRequest;
600 DriverObject->MajorFunction[IRP_MJ_CLOSE] = LstDispatchRequest;
601 DriverObject->MajorFunction[IRP_MJ_READ] = LstDispatchRequest;
602 DriverObject->MajorFunction[IRP_MJ_WRITE] = LstDispatchRequest;
603 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = LstDispatchRequest;
604 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = LstDispatchRequest;
606 return STATUS_SUCCESS;
610 cfs_enter_debugger();
612 return STATUS_UNSUCCESSFUL;