⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eppflex.c

📁 simple MIPS EJTAG u-boot loader
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "ntddk.h"
#include "string.h"
#include "ddk/parallel.h"

#include "eppflex.h"


#define printk DbgPrint
#define kmalloc(size) ExAllocatePool(NonPagedPool,size)
#define kfree ExFreePool

#if 0
#define VLOG(x)  do { x; } while (0)
#else
#define VLOG(x)  do {  } while (0)
#endif

#if 1
#define ELOG(x)  do { x; } while (0)
#else
#define ELOG(x)  do {  } while (0)
#endif

struct eppflex {
        unsigned int dummy;
};

struct eppflexfile {
        PDEVICE_OBJECT pdo;
        PFILE_OBJECT pdfo;
        PARALLEL_PORT_INFORMATION info;
        PARALLEL_PNP_INFORMATION pnpinfo;
};


static NTSTATUS parcompletion(PDEVICE_OBJECT devobj, PIRP irp, PKEVENT event)
{
        KeSetEvent(event, 0, FALSE);
        return STATUS_MORE_PROCESSING_REQUIRED;
}

static NTSTATUS callparport(struct eppflexfile *fs, unsigned long ioctlcode,
			    void *buffer, unsigned int inlen, unsigned int outlen,
			    LARGE_INTEGER *timeout)
{
        NTSTATUS status;
        PIRP irp;
        PIO_STACK_LOCATION irpsp;
        KEVENT event;

        irp = IoAllocateIrp((CCHAR)(fs->pdo->StackSize+1), FALSE);
        if (!irp)
                return STATUS_INSUFFICIENT_RESOURCES;
        irpsp = IoGetNextIrpStackLocation(irp);
        irpsp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
        irpsp->Parameters.DeviceIoControl.OutputBufferLength = outlen;
        irpsp->Parameters.DeviceIoControl.InputBufferLength = inlen;
        irpsp->Parameters.DeviceIoControl.IoControlCode = ioctlcode;
        irp->AssociatedIrp.SystemBuffer = buffer;
  
        KeInitializeEvent(&event, NotificationEvent, FALSE);
        IoSetCompletionRoutine(irp, parcompletion, &event, TRUE, TRUE, TRUE);
        status = IoCallDriver(fs->pdo, irp);
        if (!NT_SUCCESS(status)) {
                IoFreeIrp(irp);
                return status;
        }
  
        status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, timeout);
        if (status == STATUS_TIMEOUT) {
                IoCancelIrp(irp);
                status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        }
        status = irp->IoStatus.Status;
        IoFreeIrp(irp);
        return status;
}

static NTSTATUS read_port(PDEVICE_OBJECT devobj, PIRP irp, PUCHAR port)
{
        NTSTATUS status = STATUS_SUCCESS;
        PIO_STACK_LOCATION irpsp;
        PFILE_OBJECT fileobj;
        struct eppflex *s = devobj->DeviceExtension;
        struct eppflexfile *fs;
        struct eppflex_rwdata *rw = (struct eppflex_rwdata *)irp->AssociatedIrp.SystemBuffer;
  
        irpsp = IoGetCurrentIrpStackLocation(irp);
        fileobj = irpsp->FileObject;
        fs = fileobj->FsContext;

        irp->IoStatus.Information = 0;
        if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(struct eppflex_rwdata))
                status = STATUS_INVALID_PARAMETER;
        else if ((port < fs->info.Controller || port >= fs->info.Controller+fs->info.SpanOfController) &&
                 (port < fs->pnpinfo.EcpController || port >= fs->pnpinfo.EcpController+fs->pnpinfo.SpanOfEcpController))
                status = STATUS_ACCESS_VIOLATION;
        else {
                rw->data = READ_PORT_UCHAR(port);
                irp->IoStatus.Information = sizeof(struct eppflex_rwdata);
        }
        irp->IoStatus.Status = status;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        return status;
}

static NTSTATUS write_port(PDEVICE_OBJECT devobj, PIRP irp, PUCHAR port)
{
        NTSTATUS status = STATUS_SUCCESS;
        PIO_STACK_LOCATION irpsp;
        PFILE_OBJECT fileobj;
        struct eppflex *s = devobj->DeviceExtension;
        struct eppflexfile *fs;
        struct eppflex_rwdata *rw = (struct eppflex_rwdata *)irp->AssociatedIrp.SystemBuffer;
  
        irpsp = IoGetCurrentIrpStackLocation(irp);
        fileobj = irpsp->FileObject;
        fs = fileobj->FsContext;

        irp->IoStatus.Information = 0;
        if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct eppflex_rwdata))
                status = STATUS_INVALID_PARAMETER;
        else if ((port < fs->info.Controller || port >= fs->info.Controller+fs->info.SpanOfController) &&
                 (port < fs->pnpinfo.EcpController || port >= fs->pnpinfo.EcpController+fs->pnpinfo.SpanOfEcpController))
                status = STATUS_ACCESS_VIOLATION;
        else {
                WRITE_PORT_UCHAR(port, rw->data);
        }
        irp->IoStatus.Status = status;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        return status;
}

static NTSTATUS frob_port(PDEVICE_OBJECT devobj, PIRP irp, PUCHAR port)
{
        NTSTATUS status = STATUS_SUCCESS;
        PIO_STACK_LOCATION irpsp;
        PFILE_OBJECT fileobj;
        struct eppflex *s = devobj->DeviceExtension;
        struct eppflexfile *fs;
        struct eppflex_rwdata *rw = (struct eppflex_rwdata *)irp->AssociatedIrp.SystemBuffer;
        UCHAR data;

        irpsp = IoGetCurrentIrpStackLocation(irp);
        fileobj = irpsp->FileObject;
        fs = fileobj->FsContext;

        irp->IoStatus.Information = 0;
        if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct eppflex_rwdata) ||
            irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(struct eppflex_rwdata))
                status = STATUS_INVALID_PARAMETER;
        else if ((port < fs->info.Controller || port >= fs->info.Controller+fs->info.SpanOfController) &&
                 (port < fs->pnpinfo.EcpController || port >= fs->pnpinfo.EcpController+fs->pnpinfo.SpanOfEcpController))
                status = STATUS_ACCESS_VIOLATION;
        else {
                data = READ_PORT_UCHAR(port);
                data = (data & ~rw->mask) ^ rw->data;
                WRITE_PORT_UCHAR(port, data);
                rw->data = data;
                irp->IoStatus.Information = sizeof(struct eppflex_rwdata);
        }
        irp->IoStatus.Status = status;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        return status;
}

static NTSTATUS ioctl(PDEVICE_OBJECT devobj, PIRP irp)
{
        NTSTATUS status = STATUS_NOT_IMPLEMENTED;
        PIO_STACK_LOCATION irpsp;
        PFILE_OBJECT fileobj;
        struct eppflex *s = devobj->DeviceExtension;
        struct eppflexfile *fs;

        irpsp = IoGetCurrentIrpStackLocation(irp);
        fileobj = irpsp->FileObject;
        fs = fileobj->FsContext;

        VLOG(printk("eppflex: ioctl\n"));

        if (!fs) {
                status = irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
                IoCompleteRequest(irp, IO_NO_INCREMENT);
                return status;
        }
        switch (irpsp->Parameters.DeviceIoControl.IoControlCode) {
        case IOCTL_EPPFLEX_READ_DATA:
                return read_port(devobj, irp, fs->info.Controller);

        case IOCTL_EPPFLEX_WRITE_DATA:
                return write_port(devobj, irp, fs->info.Controller);

        case IOCTL_EPPFLEX_READ_STATUS:
                return read_port(devobj, irp, fs->info.Controller + 1);

        case IOCTL_EPPFLEX_WRITE_STATUS:
                return write_port(devobj, irp, fs->info.Controller + 1);

        case IOCTL_EPPFLEX_READ_CONTROL:
                return read_port(devobj, irp, fs->info.Controller + 2);

        case IOCTL_EPPFLEX_WRITE_CONTROL:
                return write_port(devobj, irp, fs->info.Controller + 2);

        case IOCTL_EPPFLEX_FROB_CONTROL:
                return frob_port(devobj, irp, fs->info.Controller + 2);

        case IOCTL_EPPFLEX_READ_ECONTROL:
                return read_port(devobj, irp, fs->pnpinfo.EcpController + 2);

        case IOCTL_EPPFLEX_WRITE_ECONTROL:
                return write_port(devobj, irp, fs->pnpinfo.EcpController + 2);

        case IOCTL_EPPFLEX_FROB_ECONTROL:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -