X-Authentication-Warning: fajnm1.am.ub.es: ofors owned process doing -bs Date: Tue, 8 Apr 2003 11:24:50 +0200 (METDST) From: Octavi Fors To: djgpp AT delorie DOT com Subject: porting PCI card driver from NT to DOS Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from QUOTED-PRINTABLE to 8bit by delorie.com id h389Q7S07391 Reply-To: djgpp AT delorie DOT com Hi all, this is my first email to the list and first time I heard from djgpp. We have recently purchased a Heidenhain PCI card which counts revolutions from a rotary encoder. Heidenhain only supplies Windows9x and NT driver, but not DOS or Win 3.11. We dispose of C source code of such driver (take a look below my message). However, our telescope control software is built and running under DOS/Win3.11. This is why I became interested with djgpp, as it seems this compilator is able to compile 32 bits C code for being run under DOS. With this in mind, I would be grateful if anybody can bring me some light on the following questions: -Could be possible to compile C source code of NT driver shown below with djgpp? With how much effort? Minor changes of syntax or major changes? Please, advice. -Is there any other more straigh forward alternative for porting NT driver for DOS instead of trying to compile it with djgpp? Thanks in advance, ================================================================= Octavi Fors Astronomy Department University of Barcelona Barcelona SPAIN e-mail: ofors AT am DOT ub DOT es ================================================================= /* Copyright (c) 1999, Dr. Johannes Heidenhain GmbH Module Name: IK220Drv.c Abstract: Windows NT kernel-mode device driver for IK 220 Notes: This kernel driver allows Win32 applications to access IK 220 hardware through DeviceIOControl. History: - Version 0.08 ES 24.06.1999 - Time out in IOCTL_BURSTRAM Version 0.15 ES 29.07.1999 - Save bus number in DEVICE_EXTENSION Version 0.16 ES 30.07.1999 - Change in resource descripton Version 0.17 ES 04.08.1999 - Version 1.0 release Version 1.00 ES 04.08.1999 ------------------------------------------------------------------------------------------ - Version 2.0 release Version 2.00 ES 19.10.1999 ------------------------------------------------------------------------------------------ - Version 3.0 release Version 3.00 ES 13.06.2000 ------------------------------------------------------------------------------------------ - Version 4.0 release Version 4.00 ES 29.10.2001 ------------------------------------------------------------------------------------------ */ #define _VERSION " 4.00" #include "ntddk.h" #include "string.h" #include "IK220DRV.h" #ifdef DBG #define kdPrint(arg) DbgPrint arg #define kdBreak DbgBreakPoint #else #define kdPrint(arg) #define kdBreak #endif typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT DeviceObject; ULONG DeviceType; ULONG BusNumber[8]; PUSHORT PortBase[16]; PULONG ConfBase[8]; ULONG DevStat; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; typedef struct _BUS_TAG { ULONG BusType; ULONG BusNumber; } BUS, *PBUS; // Function prototypes VOID IK220DrvUnload ( IN PDRIVER_OBJECT DriverObject ); NTSTATUS IK220DrvDispatch ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID IK220WriteErrorLog ( IN PDEVICE_OBJECT DeviceObject, IN ULONG EventID, IN ULONG ErrorValue ); NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, // Pointer to driver object IN PUNICODE_STRING RegistryPath) // Pointer to registry path { PDEVICE_OBJECT deviceObject; // Pointer to device object PDEVICE_EXTENSION deviceExtension; // Pointer to device extension NTSTATUS ntStatus; // NT-Status BOOLEAN Translated; // Status of HalTranslateBusAddress WCHAR nameText[] = L"\\Device\\IK220Drv"; // Name of device driver WCHAR linkText[] = L"\\DosDevices\\IK220Drv"; // DOS-Name of device driver UNICODE_STRING nameString, linkString; // Device name PHYSICAL_ADDRESS PortAddress[16], MappedAddress; // Port address of IK 220 PHYSICAL_ADDRESS ConfAddress[8]; // Address of PCI configuration register ULONG MemType = 0; // PCI bus memory mapped ULONG MemorySize = 0x20; // Card memory space size 32 Byte ULONG ConfSize = 0x54; // Configuration register space size 84 Byte ULONG index; // Card index ULONG NumberOfCards = 0; // Number of registered card's PCM_RESOURCE_LIST ResourceList = NULL; // Pointer to resource usage list to report to system CM_RESOURCE_LIST EmptyResourceList; // Empty resource usage list ULONG SizeOfResourceList = 0; // Size of resource list PCM_FULL_RESOURCE_DESCRIPTOR PFullResDesc; // Full resource descriptor PCM_PARTIAL_RESOURCE_DESCRIPTOR PPartResDesc; // Partial resource descriptor BOOLEAN ResourceConflict = TRUE; // Resouruce conflict ULONG Zero = 0x0; BUS Interface; // PCI_COMMON_CONFIG PciCommonConfig; // ULONG Slot; // Counter for PCI slots ULONG bytes; // kdPrint (( "\nIK220Drv: DriverEntry started\n" )); // Create device //////////////// RtlInitUnicodeString ( &nameString, nameText ); ntStatus = IoCreateDevice ( DriverObject, // Pointer to driver object sizeof(DEVICE_EXTENSION), // Size of device extension &nameString, // Device name FILE_DEVICE_IK220, // Device type 0, // Device characteristics TRUE, // Exclusive device &deviceObject ); // Newly created device object if (!NT_SUCCESS (ntStatus)) { kdPrint (( "IK220Drv: Can't create Device\n" )); IK220WriteErrorLog (deviceObject, 0 ,ntStatus); return ntStatus; } // Fill device object ///////////////////// deviceObject->Flags |= DO_BUFFERED_IO; deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; RtlZeroMemory ( deviceExtension, sizeof(*deviceExtension) ); deviceExtension->DeviceObject = deviceObject; deviceExtension->DeviceType = FILE_DEVICE_IK220; // Create symbolic link /////////////////////// RtlInitUnicodeString ( &linkString, linkText ); ntStatus = IoCreateSymbolicLink ( &linkString, &nameString ); if (!NT_SUCCESS (ntStatus)) { kdPrint (( "IK220Drv: Can't create symbolic link\n" )); IK220WriteErrorLog (deviceObject, 3 ,ntStatus); IoDeleteDevice (DriverObject->DeviceObject); return ntStatus; } DriverObject->DriverUnload = IK220DrvUnload; // Driver unload DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IK220DrvDispatch; // Driver dispatch // Search for IK 220 //////////////////// kdPrint (( "IK220Drv: Search for IK 220\n" )); Interface.BusType = PCIBus; Interface.BusNumber = 0; for (index=0; index<16; index++) { PortAddress[index].HighPart = 0L; PortAddress[index].LowPart = 0L; } for (index=0; index<8; index++) { ConfAddress[index].HighPart = 0L; ConfAddress[index].LowPart = 0L; } index=0; do { for (Slot=0; SlotDeviceObject); return STATUS_DEVICE_CONFIGURATION_ERROR; } else break; } else { if ( (PciCommonConfig.VendorID == VendorID_PLX) && (PciCommonConfig.DeviceID == DeviceID_PLX) ) if ( (PciCommonConfig.u.type0.SubVendorID == SVendorID_PLX) && (PciCommonConfig.u.type0.SubSystemID == SSystemID_IK220) ) { deviceExtension->BusNumber[index>>1] = Interface.BusNumber; ConfAddress[index>>1].LowPart = PciCommonConfig.u.type0.BaseAddresses[0] & 0xFFFFFFF0; kdPrint (( "IK220Drv: Bus %d Slot %d configuration register at 0x%08lX\n", Interface.BusNumber, Slot, ConfAddress[index>>1].LowPart )); PortAddress[index].LowPart = PciCommonConfig.u.type0.BaseAddresses[2] & 0xFFFFFFF0; kdPrint (( "IK220Drv: Bus %d Slot %d chip select 0 at 0x%08lX\n", Interface.BusNumber, Slot, PortAddress[index].LowPart )); index++; PortAddress[index].LowPart = PciCommonConfig.u.type0.BaseAddresses[3] & 0xFFFFFFF0; kdPrint (( "IK220Drv: Bus %d Slot %d chip select 1 at 0x%08lX\n", Interface.BusNumber, Slot, PortAddress[index].LowPart )); index++; } } } Interface.BusNumber++; } while ( (bytes!=0) && (index<16) ); NumberOfCards=0; for (index=0; index<16; index++) if (PortAddress[index].LowPart != 0) NumberOfCards++; if (NumberOfCards==0) { kdPrint (( "IK220Drv: No card found!\n" )); IK220WriteErrorLog (deviceObject, 10, 0); RtlInitUnicodeString ( &linkString, linkText ); IoDeleteSymbolicLink ( &linkString ); IoDeleteDevice (DriverObject->DeviceObject); return STATUS_DEVICE_CONFIGURATION_ERROR; } // Report resource usage to system ////////////////////////////////// kdPrint (( "IK220Drv: Report resource usage\n" )); SizeOfResourceList = 0; for ( index = 0; index<16; index=index+2 ) if (PortAddress[index].LowPart != 0) { SizeOfResourceList = SizeOfResourceList + 3 * sizeof(CM_RESOURCE_LIST); } ResourceList = ExAllocatePool ( PagedPool, SizeOfResourceList); if (ResourceList == NULL) { kdPrint (( "IK220Drv: Can't allocate memory for resource list\n" )); IK220WriteErrorLog (deviceObject, 2 , 0); RtlInitUnicodeString ( &linkString, linkText ); IoDeleteSymbolicLink ( &linkString ); IoDeleteDevice (DriverObject->DeviceObject); return STATUS_UNSUCCESSFUL; } RtlZeroMemory ( ResourceList, SizeOfResourceList); ResourceList->Count = 0; for ( index = 0; index<8; index++ ) if ( (PortAddress[index<<1].LowPart != 0) && (PortAddress[(index<<1)+1].LowPart != 0) ) { kdPrint (( "IK220Drv: Claiming resources for card %d\n", index )); // Axis 1 kdPrint (( "IK220Drv: Reporting card resource %d at 0x%08lX\n", index<<1, PortAddress[index<<1] )); ResourceList->Count++; PFullResDesc = &ResourceList->List[index*3]; PPartResDesc = &(PFullResDesc->PartialResourceList.PartialDescriptors[0]); PFullResDesc->InterfaceType = (INTERFACE_TYPE)Interface.BusType; PFullResDesc->BusNumber = deviceExtension->BusNumber[index]; PFullResDesc->PartialResourceList.Count = 1; PFullResDesc->PartialResourceList.Version = 0; PFullResDesc->PartialResourceList.Revision = 0; PPartResDesc->Type = CmResourceTypeMemory; PPartResDesc->ShareDisposition = CmResourceShareDriverExclusive; PPartResDesc->Flags = CM_RESOURCE_MEMORY_READ_WRITE; PPartResDesc->u.Memory.Start = PortAddress[index<<1]; PPartResDesc->u.Memory.Length = MemorySize; // Axis 2 kdPrint (( "IK220Drv: Reporting card resource %d at 0x%08lX\n", (index<<1)+1, PortAddress[(index<<1)+1] )); ResourceList->Count++; PFullResDesc = &ResourceList->List[index*3+1]; PPartResDesc = &(PFullResDesc->PartialResourceList.PartialDescriptors[0]); PFullResDesc->InterfaceType = (INTERFACE_TYPE)Interface.BusType; PFullResDesc->BusNumber = deviceExtension->BusNumber[index]; PFullResDesc->PartialResourceList.Count = 1; PFullResDesc->PartialResourceList.Version = 0; PFullResDesc->PartialResourceList.Revision = 0; PPartResDesc->Type = CmResourceTypeMemory; PPartResDesc->ShareDisposition = CmResourceShareDriverExclusive; PPartResDesc->Flags = CM_RESOURCE_MEMORY_READ_WRITE; PPartResDesc->u.Memory.Start = PortAddress[(index<<1)+1]; PPartResDesc->u.Memory.Length = MemorySize; // Configuration register kdPrint (( "IK220Drv: Reporting conf resource %d at 0x%08lX\n", index, ConfAddress[index] )); ResourceList->Count++; PFullResDesc = &ResourceList->List[index*3+2]; PPartResDesc = &(PFullResDesc->PartialResourceList.PartialDescriptors[0]); PFullResDesc->InterfaceType = (INTERFACE_TYPE)Interface.BusType; PFullResDesc->BusNumber = deviceExtension->BusNumber[index]; PFullResDesc->PartialResourceList.Count = 1; PFullResDesc->PartialResourceList.Version = 0; PFullResDesc->PartialResourceList.Revision = 0; PPartResDesc->Type = CmResourceTypeMemory; PPartResDesc->ShareDisposition = CmResourceShareDriverExclusive; PPartResDesc->Flags = CM_RESOURCE_MEMORY_READ_WRITE; PPartResDesc->u.Memory.Start = ConfAddress[index]; PPartResDesc->u.Memory.Length = ConfSize; } ntStatus = IoReportResourceUsage ( NULL, DriverObject, ResourceList, SizeOfResourceList, NULL, NULL, 0, FALSE, &ResourceConflict ); if (!NT_SUCCESS (ntStatus)) { kdPrint (( "IK220Drv: Resource conflict: Status = 0x%08lX\n", ntStatus)); IK220WriteErrorLog (deviceObject, 4 , ntStatus); ExFreePool (ResourceList); RtlInitUnicodeString ( &linkString, linkText ); IoDeleteSymbolicLink ( &linkString ); IoDeleteDevice (DriverObject->DeviceObject); return ntStatus; } ExFreePool (ResourceList); kdPrint (( "IK220Drv: Get hardware access\n" )); // Translate physical address to virtual address //////////////////////////////////////////////// for ( index=0; index<16; index++ ) if (PortAddress[index].LowPart != 0) { Translated = HalTranslateBusAddress ( Interface.BusType, deviceExtension->BusNumber[index>>1], PortAddress[index], &MemType, &MappedAddress ); if (!Translated) { kdPrint (( "IK220Drv: Hardware access failed Axis=%d\n", index )); IK220WriteErrorLog (deviceObject, 5, ntStatus); ntStatus = IoReportResourceUsage ( NULL, DriverObject, &EmptyResourceList, sizeof(EmptyResourceList), NULL, NULL, 0, FALSE, &ResourceConflict ); RtlInitUnicodeString ( &linkString, linkText ); IoDeleteSymbolicLink ( &linkString ); IoDeleteDevice (DriverObject->DeviceObject); return STATUS_UNSUCCESSFUL; } deviceExtension->PortBase[index] = (void*)MmMapIoSpace ( MappedAddress, MemorySize, FALSE ); kdPrint (( "IK220Drv: Axis %d mapped to 0x%08lX\n", index, deviceExtension->PortBase[index] )); } else deviceExtension->PortBase[index] = NULL; for ( index=0; index<8; index++ ) if (ConfAddress[index].LowPart != 0) { Translated = HalTranslateBusAddress ( Interface.BusType, deviceExtension->BusNumber[index], ConfAddress[index], &MemType, &MappedAddress ); if (!Translated) { kdPrint (( "IK220Drv: Hardware access failed Conf=%d\n", index )); IK220WriteErrorLog (deviceObject, 5, ntStatus); ntStatus = IoReportResourceUsage ( NULL, DriverObject, &EmptyResourceList, sizeof(EmptyResourceList), NULL, NULL, 0, FALSE, &ResourceConflict ); RtlInitUnicodeString ( &linkString, linkText ); IoDeleteSymbolicLink ( &linkString ); IoDeleteDevice (DriverObject->DeviceObject); return STATUS_UNSUCCESSFUL; } deviceExtension->ConfBase[index] = (void*)MmMapIoSpace ( MappedAddress, MemorySize, FALSE ); kdPrint (( "IK220Drv: Configuration register %d mapped to 0x%08lX\n", index, deviceExtension->ConfBase[index] )); } else deviceExtension->ConfBase[index] = NULL; kdPrint (( "IK220Drv: DriverEntry ends\n\n" )); return STATUS_SUCCESS; } VOID IK220DrvUnload ( IN PDRIVER_OBJECT DriverObject ) { WCHAR linkText[] = L"\\DosDevices\\IK220Drv"; UNICODE_STRING linkString; // Device name CM_RESOURCE_LIST EmptyResourceList; // Empty resource usage list BOOLEAN ResourceConflict; // Resource already in use kdPrint (( "IK220Drv: Driver unload\n" )); // Unload driver: remove resource usage, delete symbolic link, delete device //////////////////////////////////////////////////////////////////////////// RtlZeroMemory (&EmptyResourceList, sizeof(EmptyResourceList) ); IoReportResourceUsage ( NULL, DriverObject, &EmptyResourceList, sizeof(EmptyResourceList), NULL, NULL, 0, FALSE, &ResourceConflict ); RtlInitUnicodeString ( &linkString, linkText ); IoDeleteSymbolicLink ( &linkString ); IoDeleteDevice (DriverObject->DeviceObject); } NTSTATUS IK220DrvDispatch ( IN PDEVICE_OBJECT deviceObject, IN PIRP Irp ) { #ifdef _DEBUG const char DrvVers[20] = "DRV: V"_VERSION"(D)"; #else const char DrvVers[20] = "DRV: V"_VERSION"(R)"; #endif NTSTATUS ntStatus = STATUS_SUCCESS; // NT-Status PIO_STACK_LOCATION irpStack; ULONG ioControlCode; ULONG wordsToRead, wordsToWrite; // Number of words for i/o PUCHAR irpBufferB; // Byte buffer pointer for i/o PUSHORT irpBufferS; // Short buffer pointer for i/o PULONG irpBufferL; // Long buffer pointer for i/o ULONG i; // Loop counter USHORT cardNum, cardReg, RamAdr; // Card number / card register / RAM address USHORT* pSource; // Source pointer USHORT* pDestination; // Destination pointer ULONG* pDestinationL; // Destination pointer long USHORT Status; // Status from IK 220 USHORT TimeOut; // Time out counter PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: kdPrint (( "IK220Drv: Dispatched to create\n" )); Irp->IoStatus.Information = 0; break; case IRP_MJ_CLOSE: kdPrint (( "IK220Drv: Dispatched to close\n" )); deviceExtension->DevStat = 0; Irp->IoStatus.Information = 0; break; case IRP_MJ_READ: kdPrint (( "IK220Drv: Dispatched to read\n" )); Irp->IoStatus.Information = 0; break; case IRP_MJ_WRITE: kdPrint (( "IK220Drv: Dispatched to write\n" )); Irp->IoStatus.Information = 0; break; case IRP_MJ_DEVICE_CONTROL: kdPrint (( "IK220Drv: DeviceControl - " )); ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; switch (ioControlCode) { // // case IOCTL_INPUT: wordsToRead = irpStack->Parameters.DeviceIoControl.OutputBufferLength; wordsToRead = wordsToRead /2; irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; cardReg = *(irpBufferS+1); pSource = (USHORT*) (deviceExtension->PortBase[cardNum]); kdPrint (( "Reading %2d words card 0x%08lX register 0x%02X: ", wordsToRead, pSource, cardReg )); if (pSource) { pSource = pSource+cardReg; if (wordsToRead<=15) { kdPrint (( "0x%04X\n",*pSource )); for (i=0; iIoStatus.Information = wordsToRead*2; } else { kdPrint (( "Illegal word count!\n" )); if ((deviceExtension->DevStat & 0x1) == 0) { IK220WriteErrorLog (deviceObject, 6, wordsToRead); deviceExtension->DevStat |= 0x1; } Irp->IoStatus.Information = 0; } } else { kdPrint (( "Card not found!\n" )); if ((deviceExtension->DevStat & 0x2) == 0) { IK220WriteErrorLog (deviceObject, 7, cardNum); deviceExtension->DevStat |= 0x2; } Irp->IoStatus.Information = 0; } break; case IOCTL_OUTPUT: wordsToWrite = irpStack->Parameters.DeviceIoControl.InputBufferLength; wordsToWrite = (wordsToWrite/2)-2; irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; cardReg = *(irpBufferS+1); pSource = irpBufferS+2; pDestination = (USHORT*) (deviceExtension->PortBase[cardNum]); kdPrint (( "Writing %d words 0x%04X card 0x%X register 0x%02X: \n", wordsToWrite, *pSource, deviceExtension->PortBase[cardNum], cardReg )); if (pDestination) { pDestination = pDestination+cardReg; if (wordsToWrite<=15) { for (i=0; i<(wordsToWrite); i++) *pDestination++ = *pSource++; Irp->IoStatus.Information = wordsToWrite*2; } else { kdPrint (( "Illegal word count!\n" )); if ((deviceExtension->DevStat & 0x1) == 0) { IK220WriteErrorLog (deviceObject, 6, wordsToWrite); deviceExtension->DevStat |= 0x1; } Irp->IoStatus.Information = 0; } } else { kdPrint (( "\nCard not found!\n" )); if ((deviceExtension->DevStat & 0x2) == 0) { IK220WriteErrorLog (deviceObject, 7, cardNum); deviceExtension->DevStat |= 0x2; } Irp->IoStatus.Information = 0; } break; case IOCTL_STATUS: wordsToRead = irpStack->Parameters.DeviceIoControl.OutputBufferLength; irpBufferL = Irp->AssociatedIrp.SystemBuffer; kdPrint (( "IK-Card's at:" )); for (cardNum=0; cardNum<16; cardNum++) { if (deviceExtension->PortBase[cardNum]!=0) { pSource = (USHORT*) (deviceExtension->PortBase[cardNum]); Status = *(pSource+CodeReg); if ( Status == 0x0007 ) { *(irpBufferL+cardNum) = (ULONG)deviceExtension->PortBase[cardNum]; kdPrint (( "(%2d)=0x%08lX\n", cardNum, *(irpBufferL+cardNum) )); } else { IK220WriteErrorLog (deviceObject, 7, cardNum); *(irpBufferL+cardNum) = 0L; } } else *(irpBufferL+cardNum) = 0L; } Irp->IoStatus.Information = 16*sizeof(ULONG); break; case IOCTL_DOWNLOAD: wordsToWrite = irpStack->Parameters.DeviceIoControl.InputBufferLength; wordsToWrite = (wordsToWrite/2)-2; // Number of words to transfer irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; RamAdr = *(irpBufferS+1); pSource = irpBufferS+2; pDestination = (USHORT*) (deviceExtension->PortBase[cardNum]); kdPrint (( "Loading %d words card 0x%08lX start 0x%04X: \n", wordsToWrite, pDestination, RamAdr )); if (pDestination) { for (i=1; i<=wordsToWrite; i++) { *(pDestination + ControlReg) = BootMode; // Set CPU to boot mode do { } while ( !(*(pDestination + StatusReg) & PipeEmpty) ); // *(pDestination + DatPort0 ) = RamAdr++; // Write address to port 0 *(pDestination + DatPort1 ) = *pSource; // Write data to port 1 *(pDestination + ControlReg) = WriteRamMode; // Transfer data to address in RAM pSource++; do { } while ( !(*(pDestination + StatusReg) & PipeEmpty) ); } Irp->IoStatus.Information = wordsToWrite*2; } else { kdPrint (( "\nCard not found!\n" )); if ((deviceExtension->DevStat & 0x2) == 0) { IK220WriteErrorLog (deviceObject, 7, cardNum); deviceExtension->DevStat |= 0x2; } Irp->IoStatus.Information = 0; } break; case IOCTL_BURSTRAM: wordsToRead = irpStack->Parameters.DeviceIoControl.OutputBufferLength; // Max. number of values to transfer wordsToRead = ((wordsToRead/2)-1)/3; irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; pDestination = irpBufferS+1; pSource = (USHORT*) (deviceExtension->PortBase[cardNum]); kdPrint (( "Burstread %d values card 0x%08lX\n", wordsToRead, pSource )); if (pSource) { i=0; Status=0; do { *(pSource+CmdPort) = cmdGetRam; // Command: to IK 220 TimeOut=0; do { KeStallExecutionProcessor (1); // Wait 1µs TimeOut++; // Increment TimeOut } while ( !(*(pSource+Flag1Reg) & G28Sem0) & (TimeOut<1000) ); // Wait until finished or TimeOut if ( *(pSource+DatPort0)!=cmdGetRam ) { Status = 0x8001; break; // Error from IK 220 } if ( TimeOut>=1000) { Status = 0x8002; break; // TimeOut from IK 220 } Status = Status | *(pSource+DatPort6); if (Status & statBufferNoVal) { break; // RAM Buffer empty } *pDestination++ = *(pSource+DatPort1); // Transfer counter value *pDestination++ = *(pSource+DatPort2); *pDestination++ = *(pSource+DatPort3); i++; } while ( (iIoStatus.Information = (i*3+1)*2; } else { Irp->IoStatus.Information = (1*2); } } else { kdPrint (( "\nCard not found!\n" )); if ((deviceExtension->DevStat & 0x2) == 0) { IK220WriteErrorLog (deviceObject, 7, cardNum); deviceExtension->DevStat |= 0x2; } Irp->IoStatus.Information = 0; } break; case IOCTL_VERSION: wordsToRead = irpStack->Parameters.DeviceIoControl.OutputBufferLength; wordsToRead = wordsToRead /2; irpBufferB = Irp->AssociatedIrp.SystemBuffer; irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; pSource = (USHORT*) (deviceExtension->PortBase[cardNum]); kdPrint (( "Reading version card 0x%08lX: ", pSource )); if (pSource) { *(pSource+CmdPort) = cmdGetVersion; // Command: to IK 220 do {} while (!(*(pSource+Flag1Reg) & G28Sem0)); // Wait until finished if ( *(pSource+DatPort0)==cmdGetVersion ) // Error from IK 220 { *irpBufferB++ = *(pSource+DatPort1) >> 8; *irpBufferB++ = *(pSource+DatPort1) & 0x00FF; *irpBufferB++ = *(pSource+DatPort2) >> 8; *irpBufferB++ = *(pSource+DatPort2) & 0x00FF; *irpBufferB++ = *(pSource+DatPort3) >> 8; *irpBufferB++ = *(pSource+DatPort3) & 0x00FF; *irpBufferB++ = *(pSource+DatPort4) >> 8; *irpBufferB++ = *(pSource+DatPort4) & 0x00FF; *irpBufferB++ = *(pSource+DatPort5) >> 8; *irpBufferB++ = *(pSource+DatPort5) & 0x00FF; *irpBufferB++ = *(pSource+DatPort6) >> 8; *irpBufferB++ = *(pSource+DatPort6) & 0x00FF; *irpBufferB++ = 0; for (i=0; iIoStatus.Information = 6*2+1+sizeof(DrvVers); } else Irp->IoStatus.Information = 0; } else { kdPrint (( "Card not found!\n" )); if ((deviceExtension->DevStat & 0x2) == 0) { IK220WriteErrorLog (deviceObject, 7, cardNum); deviceExtension->DevStat |= 0x2; } Irp->IoStatus.Information = 0; } break; case IOCTL_LATCHI: irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; pDestinationL = (ULONG*) (deviceExtension->ConfBase[cardNum]); if (pDestinationL) { pDestinationL = pDestinationL + CONFREG_CNTRL; kdPrint (( "Internal latch card %d at 0x%08lX\n", cardNum, pDestinationL )); *pDestinationL = *pDestinationL & 0xFFFFFEFF; // Latch Int low KeStallExecutionProcessor (2); // Wait 2µs *pDestinationL = *pDestinationL | 0x00000100; // Latch Int high Irp->IoStatus.Information = 1; } else { kdPrint (( "Internal latch card %d not found!\n", cardNum )); Irp->IoStatus.Information = 0; } break; case IOCTL_LATCHE: irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; pDestinationL = (ULONG*) (deviceExtension->ConfBase[cardNum]); if (pDestinationL) { pDestinationL = pDestinationL + CONFREG_CNTRL; kdPrint (( "External latch card %d at 0x%08lX\n", cardNum, pDestinationL )); *pDestinationL = *pDestinationL & 0xFFFFF7FF; // Latch Ext low KeStallExecutionProcessor (2); // Wait 2µs *pDestinationL = *pDestinationL | 0x00000800; // Latch Ext high Irp->IoStatus.Information = 1; } else { kdPrint (( "External latch card %d not found!\n", cardNum )); Irp->IoStatus.Information = 0; } break; case IOCTL_SYSLED: irpBufferS = Irp->AssociatedIrp.SystemBuffer; cardNum = *irpBufferS; pDestinationL = (ULONG*) (deviceExtension->ConfBase[cardNum]); if (pDestinationL) { pDestinationL = pDestinationL + CONFREG_CNTRL; kdPrint (( "System LED card %d at 0x%08lX mode=%d\n", cardNum, pDestinationL, *(irpBufferS+1) )); if ( *(irpBufferS+1)==0 ) *pDestinationL = *pDestinationL | 0x00000004; // System LED off else *pDestinationL = *pDestinationL & 0xFFFFFFFB; // System LED on Irp->IoStatus.Information = 1; } else { kdPrint (( "System LED card %d not found!\n", cardNum )); Irp->IoStatus.Information = 0; } break; default: if ((deviceExtension->DevStat & 0x4) == 0) { IK220WriteErrorLog (deviceObject, 8 ,ioControlCode); deviceExtension->DevStat |= 0x4; } kdPrint (( "unknown funtion\n" )); ntStatus = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Information = 0; break; } break; default: if ((deviceExtension->DevStat & 0x4) == 0) { IK220WriteErrorLog (deviceObject, 8 ,0); deviceExtension->DevStat |= 0x4; } kdPrint (( "IK220Drv: Dispatched to unknown MajorFunction\n" )); ntStatus = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Information = 0; break; } Irp->IoStatus.Status = ntStatus; IoCompleteRequest (Irp,IO_NO_INCREMENT); return ntStatus; } void IK220WriteErrorLog ( IN PDEVICE_OBJECT DeviceObject, IN ULONG EventID, IN ULONG ErrorValue ) { PIO_ERROR_LOG_PACKET errorLogEntry; UCHAR EntrySize; PUCHAR StringLoc; ULONG TempError; static WCHAR ErrorBuffer[11] = L"00000000"; static WCHAR ErrorText[11][30] = { L"Can't create device ", // EventID 0: L"Can't read registry values ", // EventID 1: L"Can't allocate memory ", // EventID 2: L"Can't create symbolic link ", // EventID 3: L"Resource conflict ", // EventID 4: L"Hardware access failed ", // EventID 5: L"Illegal word count ", // EventID 6: L"Card not found ", // EventID 7: L"Unknown function ", // EventID 8: L"PCI bus doesn't exist ", // EventID 9: L"No card found " // EventID 10: }; short i; EntrySize = sizeof(IO_ERROR_LOG_PACKET) + sizeof(ErrorText[EventID]); if (ErrorValue!=0) { // Convert the error value into a string TempError = ErrorValue; for (i=9; i>=0; i--) { ErrorBuffer[i] = (WCHAR)((TempError % 10) + L'0'); TempError /= 10; } EntrySize += sizeof(ErrorBuffer); } errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( DeviceObject, EntrySize ); if (errorLogEntry != NULL) { errorLogEntry->MajorFunctionCode = (UCHAR)-1; errorLogEntry->RetryCount = (UCHAR)-1; errorLogEntry->DumpDataSize = 0; if (ErrorValue!=0) errorLogEntry->NumberOfStrings = 2; else errorLogEntry->NumberOfStrings = 1; errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET); errorLogEntry->EventCategory = 0; errorLogEntry->ErrorCode = EventID; errorLogEntry->UniqueErrorValue = ErrorValue; errorLogEntry->FinalStatus = 0; errorLogEntry->SequenceNumber = (ULONG)-1; errorLogEntry->IoControlCode = 0; errorLogEntry->DeviceOffset.QuadPart = 0; StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset; RtlCopyMemory (StringLoc, ErrorText[EventID], sizeof(ErrorText[EventID])); if (ErrorValue!=0) { while (*StringLoc) StringLoc+=sizeof(WCHAR); StringLoc+=sizeof(WCHAR); RtlCopyMemory (StringLoc, ErrorBuffer, sizeof(ErrorBuffer)); } IoWriteErrorLogEntry(errorLogEntry); } }