summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/digi/pcimac/io_core.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/digi/pcimac/io_core.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/digi/pcimac/io_core.c')
-rw-r--r--private/ntos/ndis/digi/pcimac/io_core.c435
1 files changed, 435 insertions, 0 deletions
diff --git a/private/ntos/ndis/digi/pcimac/io_core.c b/private/ntos/ndis/digi/pcimac/io_core.c
new file mode 100644
index 000000000..daa0f0f52
--- /dev/null
+++ b/private/ntos/ndis/digi/pcimac/io_core.c
@@ -0,0 +1,435 @@
+/*
+ * IO_CORE.C - core routines for IO module
+ */
+
+#include <ndis.h>
+#include <ndiswan.h>
+#include <mydefs.h>
+#include <mytypes.h>
+#include <util.h>
+#include <disp.h>
+#include <adapter.h>
+#include <idd.h>
+#include <mtl.h>
+#include <cm.h>
+#include <trc.h>
+#include <io.h>
+
+#include <dgatlas.h>
+#include <dgbrip.h>
+
+extern DRIVER_BLOCK Pcimac;
+
+/* store location for prev. ioctl handler */
+extern NTSTATUS (*PrevIoctl)(DEVICE_OBJECT* DeviceObject, IRP* Irp);
+
+/* ioctl filter */
+NTSTATUS
+PcimacIoctl(DEVICE_OBJECT *DeviceObject, IRP *Irp)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
+ NTSTATUS ini_exec_irp(IRP* irp, IO_STACK_LOCATION* irpsp);
+
+ /* must be an ioctl, else pass this one */
+ if ( irpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL )
+ {
+ NdisReleaseSpinLock(&Pcimac.lock);
+
+ return(PrevIoctl(DeviceObject, Irp));
+ }
+
+ /* must be our own private ioctl code */
+
+ switch( irpSp->Parameters.DeviceIoControl.IoControlCode )
+ {
+ case IO_IOCTL_PCIMAC_EXEC:
+ case DIGI_ATLAS_IOCTL:
+ break;
+ }
+
+ /* one of our own, execute */
+ Irp->IoStatus.Information = 0L;
+ ExecIrp(Irp, irpSp);
+
+ /* complete irp */
+ Irp->IoStatus.Status = status;
+ IoSetCancelRoutine (Irp, NULL);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(status);
+}
+
+/* execute ioctl irp */
+NTSTATUS
+ExecIrp(IRP *irp, IO_STACK_LOCATION *irpsp)
+{
+ UCHAR *in_buf, *out_buf;
+ ULONG in_len, out_len;
+ NTSTATUS stat;
+
+ /* establish in/out buffers */
+ out_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
+ in_len = irpsp->Parameters.DeviceIoControl.InputBufferLength;
+
+
+ /* in/out length must be the same */
+ if ( in_len != out_len )
+ return(STATUS_UNSUCCESSFUL);
+
+ switch( irpsp->Parameters.DeviceIoControl.IoControlCode )
+ {
+ case IO_IOCTL_PCIMAC_EXEC:
+ out_buf = irp->UserBuffer;
+ in_buf = irp->AssociatedIrp.SystemBuffer;
+ /* copy in buffer into output buffer */
+ NdisMoveMemory(out_buf, in_buf, out_len);
+
+ /* execute command in place */
+ if ( (stat = io_execute((IO_CMD*)out_buf,irp)) == IO_E_PENDING)
+ /* event added pend irp */
+ return (STATUS_PENDING);
+ else
+ /* return success */
+ return(STATUS_SUCCESS);
+
+ break;
+
+ case DIGI_ATLAS_IOCTL:
+ {
+ PATLAS_PDU_HEADER Atlas;
+
+ //
+ // We need to decapsulate the DIGI_Opcode wrapper to get to
+ // the IO_CMD
+ //
+
+ out_buf = irp->AssociatedIrp.SystemBuffer;
+ in_buf = irp->AssociatedIrp.SystemBuffer;
+ Atlas = (PATLAS_PDU_HEADER)out_buf;
+
+ switch( Atlas->dwCommand )
+ {
+ case EnumAdapters:
+ {
+ ULONG n, m, NumberOfAdapters;
+ PDIGI_SYSTEM SystemInfo;
+
+ //
+ // We need to let Atlas know about all the adapters
+ // we are controlling.
+ //
+ SystemInfo = (PDIGI_SYSTEM)GET_PAYLOAD(Atlas);
+ NumberOfAdapters = EnumAdaptersInSystem();
+
+ for( n = 0, m = 0; n < NumberOfAdapters; n++ )
+ {
+ ADAPTER *Adapter = GetAdapterByIndex(n);
+
+ if( Adapter )
+ {
+ PDIGI_ADAPTER AtlasAdapterInfo;
+
+ AtlasAdapterInfo = &SystemInfo->Adapters[m];
+
+ AtlasAdapterInfo->dwMemoryAddress = Adapter->BaseMem;
+
+ if( Adapter->BaseMem )
+ AtlasAdapterInfo->dwMemoryRange = 0x4000;
+ else
+ AtlasAdapterInfo->dwMemoryRange = 0;
+
+ AtlasAdapterInfo->dwIOAddress = Adapter->BaseIO;
+ AtlasAdapterInfo->dwIORange = 8;
+
+ AtlasAdapterInfo->dwInterruptNumber = 0;
+ AtlasAdapterInfo->dwDMA = 0;
+
+ AtlasAdapterInfo->dwPersonalities = 1;
+ AtlasAdapterInfo->Personalities[0].dwPersonalityTag = DIGI_PERSONALITY_BRI;
+ AtlasAdapterInfo->Personalities[0].dwId = (DWORD)Adapter;
+
+ NdisMoveMemory( AtlasAdapterInfo->Personalities[0].szDesc,
+ Adapter->Name,
+ BRI_MAX_NAMELEN );
+
+ m++;
+ }
+ }
+
+ SystemInfo->dwAdapters = m;
+
+ irp->IoStatus.Information = out_len;
+ break;
+ } // end case EnumAdapters:
+
+ case BRIOldMethod:
+ {
+ PDIGI_OLD_METHOD OldMethodInfo;
+
+ OldMethodInfo = (PDIGI_OLD_METHOD)GET_PAYLOAD(Atlas);
+
+ //
+ // We decapsulate the Atlas stuff and feed through the
+ // old method of getting this information.
+ //
+ if( (stat = io_execute( &(OldMethodInfo->ioCmd),
+ irp )) == IO_E_PENDING )
+ /* event added pend irp */
+ return (STATUS_PENDING);
+ else
+ {
+ irp->IoStatus.Information = out_len;
+ return(STATUS_SUCCESS);
+ }
+
+ break;
+ }
+ }
+
+ break;
+
+ }
+ }
+
+}
+
+
+/* execute an io command */
+INT
+io_execute(IO_CMD *cmd, VOID *Irp_1)
+{
+ IRP *Irp = (IRP*)Irp_1;
+
+ D_LOG(D_ENTRY, ("io_execute: entry, cmd: 0x%lx\n", cmd));
+
+ /* check signature & version */
+ if ( cmd->sig != IO_CMD_SIG )
+ return(IO_E_BADSIG);
+ if ( (cmd->ver_major != IO_VER_MAJOR) ||
+ (cmd->ver_minor != IO_VER_MINOR) )
+ return(IO_E_BADVER);
+
+ D_LOG(D_ALWAYS, ("io_execute: opcode: 0x%x, cm: 0x%lx, idd: 0x%lx\n", \
+ cmd->opcode, cmd->cm, cmd->idd));
+ D_LOG(D_ALWAYS, ("io_execute: args: 0x%x 0x%x 0x%x 0x%x\n", \
+ cmd->arg[0], cmd->arg[1], cmd->arg[2], cmd->arg[3]));
+
+
+ /* clear status, assume success */
+ cmd->status = IO_E_SUCC;
+
+ /* branch on opcode */
+ switch ( cmd->opcode )
+ {
+
+ case IO_CMD_ENUM_ADAPTERS :
+ cmd->status = IoEnumAdapter(cmd);
+ break;
+
+ case IO_CMD_ENUM_CM:
+ cmd->status = IoEnumCm(cmd);
+ break;
+
+ case IO_CMD_ENUM_IDD :
+ cmd->status = IoEnumIdd(cmd);
+ break;
+
+ case IO_CMD_TRC_RESET :
+ cmd->status = trc_control(cmd->idd,
+ TRC_OP_RESET, (ULONG)cmd->idd);
+ break;
+
+ case IO_CMD_TRC_STOP :
+ cmd->status = trc_control(cmd->idd,
+ TRC_OP_STOP, (ULONG)cmd->idd);
+ break;
+
+ case IO_CMD_TRC_START :
+ cmd->status = trc_control(cmd->idd,
+ TRC_OP_START, (ULONG)cmd->idd);
+ break;
+
+ case IO_CMD_TRC_SET_FILT :
+ cmd->status = trc_control(cmd->idd,
+ TRC_OP_SET_FILTER, cmd->arg[0]);
+ break;
+
+ case IO_CMD_IDD_RESET_AREA :
+ cmd->status = idd_reset_area(cmd->idd);
+ break;
+
+ case IO_CMD_IDD_GET_AREA :
+ cmd->status = idd_get_area(cmd->idd, cmd->arg[0], NULL, NULL);
+ break;
+
+ case IO_CMD_IDD_GET_STAT :
+ cmd->status = idd_get_area_stat(cmd->idd, &cmd->val.IddStat);
+ break;
+
+ case IO_CMD_TRC_CREATE:
+ cmd->status = trc_control(cmd->idd,
+ TRC_OP_CREATE, cmd->arg[0]);
+ break;
+
+ case IO_CMD_TRC_DESTROY:
+ cmd->status = trc_control(cmd->idd,
+ TRC_OP_DESTROY, cmd->arg[0]);
+ break;
+
+ case IO_CMD_TRC_GET_STAT :
+ cmd->status = trc_get_status(idd_get_trc(cmd->idd),
+ &cmd->val.trc_stat);
+ break;
+
+ case IO_CMD_TRC_GET_ENT :
+ cmd->status = trc_get_entry(idd_get_trc(cmd->idd),
+ cmd->arg[0], &cmd->val.trc_ent);
+ break;
+
+ case IO_CMD_DBG_LEVEL :
+ DigiDebugLevel = (INT)(cmd->arg[0]);
+ break;
+
+ case IO_CMD_DO_IDP_CMD:
+ DbgPrint("DoIdpCmd: Cmd: 0x%x\n", cmd->arg[0]);
+ if( cmd->idd && (( ((IDD*)cmd->idd)->btype != IDD_BT_DATAFIREU) &&
+ ( ((IDD*)cmd->idd)->btype != IDD_BT_DATAFIREST) &&
+ ( ((IDD*)cmd->idd)->btype != IDD_BT_DATAFIRE4ST)) )
+ {
+ switch (cmd->arg[0])
+ {
+ case GET_IDP_IO_VALUE:
+ cmd->val.IdpRaw.uc = IdpGetUByteIO(cmd->idd,
+ cmd->val.IdpRaw.us);
+ cmd->status = IO_E_SUCC;
+ break;
+
+
+ case GET_IDP_BUFFER:
+ IdpGetBuffer(cmd->idd,
+ cmd->val.IdpRaw.Bank,
+ cmd->val.IdpRaw.Page,
+ cmd->val.IdpRaw.Address,
+ cmd->val.IdpRaw.Length,
+ cmd->val.IdpRaw.Buffer);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case SET_IDP_IO_VALUE:
+ IdpPutUByteIO(cmd->idd,
+ (USHORT)cmd->val.IdpRaw.Address,
+ cmd->val.IdpRaw.uc);
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case SET_IDP_BUFFER:
+ IdpPutBuffer(cmd->idd,
+ cmd->val.IdpRaw.Bank,
+ cmd->val.IdpRaw.Page,
+ cmd->val.IdpRaw.Address,
+ cmd->val.IdpRaw.Length,
+ cmd->val.IdpRaw.Buffer);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ default:
+ cmd->status = IO_E_BADCMD;
+ break;
+ }
+ }
+ else
+ cmd->status = IO_E_BADIDD;
+ break;
+
+ case IO_CMD_DO_ADP_CMD:
+ if( cmd->idd && (( ((IDD*)cmd->idd)->btype == IDD_BT_DATAFIREU) ||
+ ( ((IDD*)cmd->idd)->btype == IDD_BT_DATAFIREST) ||
+ ( ((IDD*)cmd->idd)->btype == IDD_BT_DATAFIRE4ST)) )
+ {
+ switch (cmd->arg[0])
+ {
+ case GET_ADP_UCHAR:
+ cmd->val.AdpRaw.uc = AdpGetUByte(cmd->idd,
+ cmd->val.AdpRaw.Address);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case GET_ADP_USHORT:
+ cmd->val.AdpRaw.us = AdpGetUShort(cmd->idd,
+ cmd->val.AdpRaw.Address);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case GET_ADP_ULONG:
+ cmd->val.AdpRaw.ul = AdpGetULong(cmd->idd,
+ cmd->val.AdpRaw.Address);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case GET_ADP_BUFFER:
+ AdpGetBuffer(cmd->idd,
+ cmd->val.AdpRaw.Buffer,
+ cmd->val.AdpRaw.Address,
+ cmd->val.AdpRaw.Length
+ );
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case SET_ADP_UCHAR:
+ AdpPutUByte(cmd->idd,
+ cmd->val.AdpRaw.Address,
+ cmd->val.AdpRaw.uc);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case SET_ADP_USHORT:
+ AdpPutUShort(cmd->idd,
+ cmd->val.AdpRaw.Address,
+ cmd->val.AdpRaw.us);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case SET_ADP_ULONG:
+ AdpPutULong(cmd->idd,
+ cmd->val.AdpRaw.Address,
+ cmd->val.AdpRaw.ul);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ case SET_ADP_BUFFER:
+ AdpPutBuffer(cmd->idd,
+ cmd->val.AdpRaw.Address,
+ cmd->val.AdpRaw.Buffer,
+ cmd->val.AdpRaw.Length);
+
+ cmd->status = IO_E_SUCC;
+ break;
+
+ default:
+ cmd->status = IO_E_BADCMD;
+ break;
+ }
+ }
+ else
+ cmd->status = IO_E_BADIDD;
+
+ break;
+
+ default :
+ cmd->status = IO_E_BADCMD;
+ break;
+ }
+
+ /* return status code */
+ return((INT)cmd->status);
+}