4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
34 * winnt selftest driver framework
38 #define DEBUG_SUBSYSTEM S_LNET
45 #include <libcfs/libcfs.h>
48 /* libcfs module init/exit routines */
49 DECLARE_INIT(init_libcfs_module);
50 DECLARE_EXIT(exit_libcfs_module);
52 /* portal module init/exit routines */
53 DECLARE_INIT(init_lnet);
54 DECLARE_EXIT(fini_lnet);
56 /* tdinal module init/exit routines */
57 DECLARE_INIT(ksocknal_module_init);
58 DECLARE_EXIT(ksocknal_module_fini);
60 /* selftest module init/exit routines */
61 DECLARE_INIT(lnet_selftest_init);
62 DECLARE_EXIT(lnet_selftest_fini);
68 struct module libcfs_global_module = {"selftest"};
71 * structure definitions
74 #define LNET_SELFTEST_VERSION 0x00010001 /* LNET selftest module version */
76 #define LNET_SELFTEST_DEVICE L"\\Device\\Selftest" /* device object name */
77 #define LNET_SELFTEST_SYMLNK L"\\DosDevices\\Selftest" /* user-visible name for the device*/
79 typedef struct _DEVICE_EXTENSION {
81 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
87 PDEVICE_OBJECT SelfObject = NULL; /* lnet selftest object */
88 PDEVICE_OBJECT ProcObject = NULL; /* procfs emulator device */
97 // complete Irp request ...
107 Irp->IoStatus.Status = Status;
108 Irp->IoStatus.Information = Info;
109 IoCompleteRequest(Irp,IO_NO_INCREMENT);
115 // Open/Create Device ...
120 IN PDEVICE_OBJECT DeviceObject,
124 KdPrint(("LstCreate: DeviceCreate ...\n"));
126 return LstCompleteIrp(Irp,STATUS_SUCCESS,0);
135 IN PDEVICE_OBJECT DeviceObject,
138 KdPrint(("LstClose: Device Closed.\n"));
140 return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
142 UNREFERENCED_PARAMETER(DeviceObject);
147 // computer is being shut down
152 IN PDEVICE_OBJECT DeviceObject,
156 KdPrint(("LstShutdown: ...\n"));
158 return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
160 UNREFERENCED_PARAMETER(DeviceObject);
170 IN PDEVICE_OBJECT DeviceObject,
174 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
175 PIO_STACK_LOCATION IrpSp;
183 Irp->IoStatus.Information = 0;
184 IrpSp = IoGetCurrentIrpStackLocation(Irp);
186 ControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
187 InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
188 OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
189 lpvInBuffer = Irp->AssociatedIrp.SystemBuffer;
191 ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
195 case IOCTL_LIBCFS_VERSION:
197 *((ULONG *)lpvInBuffer) = (ULONG)(LNET_SELFTEST_VERSION);
198 Irp->IoStatus.Information = sizeof(ULONG);
199 Status = STATUS_SUCCESS;
206 Irp->IoStatus.Status = Status;
207 IoCompleteRequest(Irp, IO_NO_INCREMENT);
214 IN PDEVICE_OBJECT DeviceObject,
219 PIO_STACK_LOCATION IrpSp;
221 FILE_FULL_EA_INFORMATION *ea;
224 IrpSp = IoGetCurrentIrpStackLocation(Irp);
225 ea = (PFILE_FULL_EA_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
228 Status = STATUS_INVALID_PARAMETER;
230 fp = lustre_open_file(&ea->EaName[0]);
232 Status = STATUS_OBJECT_NAME_NOT_FOUND;
234 IrpSp->FileObject->FsContext = fp;
235 IrpSp->FileObject->FsContext2 = fp->private_data;
236 Status = STATUS_SUCCESS;
240 return LstCompleteIrp(Irp, Status, 0);
249 IN PDEVICE_OBJECT DeviceObject,
252 PIO_STACK_LOCATION IrpSp;
256 IrpSp = IoGetCurrentIrpStackLocation(Irp);
257 fp = (file_t *) IrpSp->FileObject->FsContext;
259 ASSERT(IrpSp->FileObject->FsContext2 == fp->private_data);
261 lustre_close_file(fp);
263 return LstCompleteIrp(Irp, STATUS_SUCCESS, 0);
265 UNREFERENCED_PARAMETER(DeviceObject);
269 * proc frame routines
274 IN PDEVICE_OBJECT DeviceObject,
278 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
279 PIO_STACK_LOCATION IrpSp;
287 Irp->IoStatus.Information = 0;
288 IrpSp = IoGetCurrentIrpStackLocation(Irp);
290 ControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
291 InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
292 OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
293 lpvInBuffer = Irp->AssociatedIrp.SystemBuffer;
295 ASSERT (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
299 case IOCTL_LIBCFS_VERSION:
301 *((ULONG *)lpvInBuffer) = (ULONG)(LNET_SELFTEST_VERSION);
302 Irp->IoStatus.Information = sizeof(ULONG);
304 Status = STATUS_SUCCESS;
308 case IOCTL_LIBCFS_ENTRY:
313 fp = (struct file *)IrpSp->FileObject->FsContext;
318 rc = lustre_ioctl_file(fp, (PCFS_PROC_IOCTL) lpvInBuffer);
321 ((PCFS_PROC_IOCTL) lpvInBuffer)->rc = rc;
322 Irp->IoStatus.Information = InputLength;
323 Status = STATUS_SUCCESS;
327 Irp->IoStatus.Status = Status;
328 IoCompleteRequest(Irp, IO_NO_INCREMENT);
335 ProcReadWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
337 PIO_STACK_LOCATION IrpSp;
344 IrpSp = IoGetCurrentIrpStackLocation(Irp);
345 if (Irp->MdlAddress) {
346 buf = MmGetSystemAddressForMdlSafe(
350 buf = Irp->AssociatedIrp.SystemBuffer;
354 Status = STATUS_SUCCESS;
357 fp = (struct file *)IrpSp->FileObject->FsContext;
360 Status = STATUS_INVALID_PARAMETER;
364 if (IrpSp->MajorFunction == IRP_MJ_READ) {
365 rc = lustre_read_file(
366 fp, IrpSp->Parameters.Read.ByteOffset.LowPart,
367 IrpSp->Parameters.Read.Length, buf);
369 rc = lustre_write_file(
370 fp, IrpSp->Parameters.Write.ByteOffset.LowPart,
371 IrpSp->Parameters.Write.Length, buf);
374 cfs_enter_debugger();
375 Status = STATUS_UNSUCCESSFUL;
377 Status = STATUS_SUCCESS;
383 return LstCompleteIrp(Irp, Status, rc);
388 // common dispatch routines
393 IN PDEVICE_OBJECT DeviceObject,
398 PIO_STACK_LOCATION IrpSp;
400 Status = STATUS_INVALID_DEVICE_REQUEST;
404 IrpSp = IoGetCurrentIrpStackLocation(Irp);
406 switch (IrpSp->MajorFunction) {
409 if (DeviceObject == SelfObject) {
410 Status = LstCreate(DeviceObject, Irp);
411 } else if (DeviceObject == ProcObject) {
412 Status = ProcCreate(DeviceObject, Irp);
417 if (DeviceObject == SelfObject) {
418 Status = LstClose(DeviceObject, Irp);
419 } else if (DeviceObject == ProcObject) {
420 Status = ProcClose(DeviceObject, Irp);
426 if (DeviceObject == ProcObject) {
427 Status = ProcReadWrite(DeviceObject, Irp);
431 case IRP_MJ_DEVICE_CONTROL:
432 if (DeviceObject == SelfObject) {
433 Status = LstDeviceControl(DeviceObject, Irp);
434 } else if (DeviceObject == ProcObject) {
435 Status = ProcDeviceControl(DeviceObject, Irp);
439 case IRP_MJ_SHUTDOWN:
440 Status = LstShutdown(DeviceObject, Irp);
445 KdPrint(("LstDispatchRequest: Major Function: %xh is not supported.\n",
446 IrpSp->MajorFunction));
447 LstCompleteIrp(Irp, Status, 0);
459 // create a device object and a dosdevice symbol link
464 IN PDRIVER_OBJECT DriverObject,
465 IN PWCHAR DeviceName,
466 IN PWCHAR SymlnkName,
472 UNICODE_STRING NtDevName;
473 UNICODE_STRING Win32DevName;
475 PDEVICE_EXTENSION DeviceExtension;
476 PDEVICE_OBJECT DeviceObject;
478 /* create the device object with the specified name */
480 RtlInitUnicodeString(&NtDevName, DeviceName);
482 Status = IoCreateDevice(
484 sizeof(DEVICE_EXTENSION),
491 if (!NT_SUCCESS(Status)) {
493 cfs_enter_debugger();
497 /* create the symlink to make the device visible to user */
499 RtlInitUnicodeString(&Win32DevName, SymlnkName);
500 Status = IoCreateSymbolicLink(&Win32DevName, &NtDevName);
502 if (!NT_SUCCESS(Status)) {
504 IoDeleteDevice(DeviceObject);
508 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceObjectExtension;
509 DeviceExtension->bProcFS = bProcFS;
511 DeviceObject->AlignmentRequirement = 0;
512 DeviceObject->SectorSize = 0;
513 DeviceObject->Flags |= DO_BUFFERED_IO;
514 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
523 NTSTATUS DriverEntry(
524 IN PDRIVER_OBJECT DriverObject,
525 IN PUNICODE_STRING RegistryPath
528 KdPrint(("LNet selftest: Build Time: " __DATE__ " " __TIME__ "\n"));
529 KdPrint(("LNet selftest: DriverEntry ... \n"));
531 /* initialize libcfs module */
532 if (module_init_libcfs_module() != 0) {
533 KdPrint(("selftest: failed to initialize module: libcfs ...\n"));
537 /* initialize portals module */
538 if (module_init_lnet() != 0) {
539 KdPrint(("selftest: failed to initialize module: lnet ...\n"));
540 module_exit_libcfs_module();
544 /* initialize tdinal module */
545 if (module_ksocknal_module_init() != 0) {
546 KdPrint(("selftest: failed to initialize module: socklnd ...\n"));
548 module_exit_libcfs_module();
552 /* initialize lnet selttest module */
553 if (module_lnet_selftest_init() != 0) {
554 KdPrint(("selftest: failed to initialize module: selftest ...\n"));
555 module_ksocknal_module_fini();
557 module_exit_libcfs_module();
561 /* create lnet selftest device object */
562 SelfObject = LstCreateDevice(
564 LNET_SELFTEST_DEVICE,
565 LNET_SELFTEST_SYMLNK,
568 KdPrint(("selftest: failed to allocate DeviceObject ...\n"));
569 module_lnet_selftest_fini();
570 module_ksocknal_module_fini();
572 module_exit_libcfs_module();
574 return STATUS_INSUFFICIENT_RESOURCES;
577 /* create the libcfs proc fs emultor device object */
578 ProcObject = LstCreateDevice(
585 KdPrint(("selftest: failed to allocate proc DeviceObject ...\n"));
586 /* remove Selftest DeviceObject */
587 IoDeleteDevice(SelfObject);
588 module_lnet_selftest_fini();
589 module_ksocknal_module_fini();
591 module_exit_libcfs_module();
592 return STATUS_INSUFFICIENT_RESOURCES;
595 /* initialize the driver callback routines */
597 DriverObject->MajorFunction[IRP_MJ_CREATE] = LstDispatchRequest;
598 DriverObject->MajorFunction[IRP_MJ_CLOSE] = LstDispatchRequest;
599 DriverObject->MajorFunction[IRP_MJ_READ] = LstDispatchRequest;
600 DriverObject->MajorFunction[IRP_MJ_WRITE] = LstDispatchRequest;
601 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = LstDispatchRequest;
602 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = LstDispatchRequest;
604 return STATUS_SUCCESS;
608 cfs_enter_debugger();
610 return STATUS_UNSUCCESSFUL;