// spin_unlock_irqrestore - ? // wake_up_interruptible - ? // free_irq - ? // request_irq - ? // spin_lock_irqsave - ? // interruptible_sleep_on_timeout -? // HZ - Количество прерываний сист. таймера за секунду // jiffies - Счетчик тиков системного таймера // cif_wait_com - пересмотреть для DOS32 !!! #define T_Shedule 0 //Использовать для ожидания shedule #include "complex.h" #include "pci.h" #include "cif_i.h" #include "cif_rcs.h" #include "cif.h" #include "dpmi.h" #include "screen.h" //#ifndef HZ //#define HZ 18 //#endif #define PCI_SUB_VENDOR_ID 0x2C #define PCI_SUB_SYSTEM_ID 0x2E unsigned short get_CS(); #pragma aux get_CS = "mov ax,cs" value[ax]; unsigned long ulRegisterSave = 0x0UL; unsigned long ulIrqCtrlRegSave = 0x0UL; unsigned char *IrqCtrlRegAddr; unsigned short cif_base = 0x00; unsigned char bData = 0x00; /* ---------------------------------------------------------------------- */ /* Locals */ /* ---------------------------------------------------------------------- */ #define DEV_IDENTIFIER_ANZ 4 #define DEV_IDENTIFIER_LEN 3 unsigned char abDevIdentifier[DEV_IDENTIFIER_ANZ][DEV_IDENTIFIER_LEN] = { {'C','I','F'}, {'C','O','M'}, {'C','O','P'}, {'D','E','V'} }; unsigned char abTestDPM [DEV_IDENTIFIER_LEN] = { 0x55, 0xAA, 0x00 }; /* ------------------------------------------------------------------------------------ */ /* driver state definitions */ /* ------------------------------------------------------------------------------------ */ #define INI_MSG_WAIT 0x00 #define INI_MSG_RUN 0x40 #define INI_MSG_RDY 0x80 #define INI_MSG_RDYRUN 0xC0 #define COM_FLAG_RDY 0x20 #define RESET_MSG_NON 0x00 #define RESET_MSG_RUN 0x01 #define EXCHGIO_NON 0x00 #define EXCHGIO_EQUAL 0x01 #define EXCHGIO_NOT_EQUAL 0x02 #ifndef CIF_NR_DEVS #define CIF_NR_DEVS 4 #endif static unsigned int addresses[] = { 0x10, //PCI_BASE_ADDRESS_0 0x14, //PCI_BASE_ADDRESS_1 0x18, //PCI_BASE_ADDRESS_2 0x1c, //PCI_BASE_ADDRESS_3 0x20, //PCI_BASE_ADDRESS_4 0x24, //PCI_BASE_ADDRESS_5 0 }; int cif_major = CIF_MAJOR; int cif_nr_devs = 0;// max: CIF_MAX_BOARDS; /* number of cif devices */ controller *CIF_CTR[4] = {NULL,NULL,NULL,NULL}; DEV_INSTANCE *cif_devices; int counter_interrupt=0; int STAT_CIF[4] = {0,0,0,0}; struct Spar_bus { unsigned char bMax_Retry_Limit; unsigned char bTQUI; unsigned short usTSL; unsigned char bTSET; unsigned short usMin_TSDR; unsigned short usMax_TSDR; unsigned long ulTTR; unsigned char bG; }Spar_bus1; struct Spar_bus par_bus[] = { {1,0, 100, 1,11,60 ,11520,10}, //0 9.6 {1,0, 100, 1,11,60 ,11520,10}, //1 19.2 {1,0, 100, 1,11,60 ,11520,10}, //2 93.75 {1,0, 100, 1,11,60 ,11520,10}, //3 187.5 {1,0, 200, 1,11,100,11520,10}, //4 500 {1,0, 300, 1,11,150,11520,10}, //5 1000 {1,0, 300, 1,11,150,11520,10}, //6 1500 {2,3, 400, 4,11,250,13824, 1}, //7 3000 {3,6, 600, 8,11,450,13824, 1}, //8 6000 {4,9,1000,16,11,800,13824, 1}, //9 12000 }; //********* Prototipes ********************** short DevInitBoard ( unsigned short usDevNumber); short DevGetInfo ( unsigned short usDevNumber, unsigned short usInfoArea, unsigned short usSize, void *pvData); //************************************************************************* //* cif_scan_pci () * //* Scan PCI-bus / detect CIF50 boards * //************************************************************************* int cif_scan_pci () { unsigned short usSubVendor, usSubSystem; DEV_INSTANCE *dev; if(!pci_bios_available()) { int i = 0; unsigned long mask, curr, tmp; unsigned int ulDPMByteSize = 0x0UL, stat; unsigned short dev_index=0,index = 0; while(!pci_dev_find(dev_index, &stat, VENDOR_ID, DEVICE_ID)) { PCIReadConfRegWord(stat,stat>>8,PCI_SUB_VENDOR_ID, &usSubVendor); PCIReadConfRegWord(stat,stat>>8,PCI_SUB_SYSTEM_ID, &usSubSystem); if( SUBVENDOR_ID == usSubVendor && SUBSYSTEM_ID == usSubSystem && index < 4) { ulDPMByteSize = 0x0UL; for(i=0; addresses[i]; i++) { PCIReadConfRegDword(stat,stat>>8,addresses[i], &curr); _asm{cli}; if(i == 2) ulRegisterSave = curr; if(i == 1) cif_base = (unsigned short)(curr & 0xFFFFFFFE); if(i == 0) IrqCtrlRegAddr = curr; PCIWriteConfRegDword(stat,stat>>8,addresses[i], ~0); PCIReadConfRegDword(stat,stat>>8,addresses[i], &mask); PCIWriteConfRegDword(stat,stat>>8,addresses[i], curr); _asm{sti}; if(i == 2) ulDPMByteSize = ~(mask & PCI_BASE_ADDRESS_IO_MASK) +1; } // if(!dpmi_map_physical(IrqCtrlRegAddr,0x50)) bData= IrqCtrlRegAddr[PCI_INTCTRLSTS_REG]; // bData = (unsigned char)(bData | HW_INTERRUPT_ENABLE);//(bData & ~HW_INTERRUPT_ENABLE); // Desable Interrupt // if(!dpmi_map_physical(IrqCtrlRegAddr,0x50)); // IrqCtrlRegAddr[PCI_INTCTRLSTS_REG]=IrqCtrlRegAddr[PCI_INTCTRLSTS_REG] | HW_INTERRUPT_ENABLE; // printf("test IRQ %x\n",IrqCtrlRegAddr[PCI_INTCTRLSTS_REG]); // eprintf(GRAY_,"CIF adr(%xh,%xh,%xh)",IrqCtrlRegAddr,cif_base,ulRegisterSave); if( cif_nr_devs == 0) { cif_devices = (DEV_INSTANCE *)malloc(sizeof (DEV_INSTANCE)); if (!cif_devices) return 0; memset(cif_devices, 0, sizeof (DEV_INSTANCE)); cif_nr_devs++; dev = (DEV_INSTANCE *)cif_devices; dev->next = NULL; } else { dev = (DEV_INSTANCE *)cif_devices; while ( dev->next) dev = (DEV_INSTANCE *)dev->next; dev->next = (DEV_INSTANCE *)malloc(sizeof(DEV_INSTANCE)); if (!dev->next) return 0; memset(dev->next, 0, sizeof(DEV_INSTANCE)); dev = (DEV_INSTANCE *)dev->next; dev->next = NULL; cif_nr_devs++; } PCIReadConfRegDword(stat,stat>>8,0x3c,&tmp); dev->usBoardIrq=tmp&0xff; dev->usBoard = index; dev->ucPCIBusNumber = stat; dev->IrqCtrlRegAddr = (unsigned char *)IrqCtrlRegAddr; dev->usBoardIrq_scanned = dev->usBoardIrq; // save it, needed while switching between irq and polling modes dev->ulBoardAddress = ulRegisterSave & PCI_BASE_ADDRESS_IO_MASK; dev->ulDPMByteSize = ulDPMByteSize; dev->ulDPMSize = ulDPMByteSize / 1024; dev->bActive = TRUE; dev->ucBusType = BUS_TYPE_PCI; dev->usBoardIrq = 0x00; //No interrupt !! index++; } dev_index++; } if(index == 0) return 0; return index; } return 0; } //************************************************************************* //* Interrupt handler * //************************************************************************* //static void cif_interrupt(int irq, void *dev_id, struct pt_regs *regs) __interrupt cif_interrupt() { DEV_INSTANCE *dev = cif_devices; unsigned char bHostFlags; // Interrupt context can use plain spin_lock() form because // interrupts are disabled inside an interrupt handler. // spin_lock (&dev->mutex); // Clear device interrupt by reading the host flags bHostFlags = *(dev->pbHostFlags); dev->bHostFlags = bHostFlags; // only for information dev->tStateInfo.IRQCnt++; // increment irq counter if((bHostFlags & INI_MSG_RDY)==0x00) { /* Reset on DEV is running */ dev->bMyDevFlags = 0x00; dev->bReadMsgFlag = HOST_MBX_EMPTY; dev->bWriteMsgFlag = DEVICE_MBX_FULL; dev->bInitMsgFlag = INI_MSG_WAIT; dev->bExIOFlag = EXCHGIO_NON; dev->bStateFlag = STATE_ERR_NON; } else { if(dev->bInitMsgFlag == INI_MSG_WAIT ) // get actual init state dev->bInitMsgFlag = (unsigned char)(bHostFlags & INI_MSG_RDYRUN); // check if message is available if(((bHostFlags ^ dev->bMyDevFlags) & HOSTCOM_FLAG) != 0x00 ) dev->bReadMsgFlag = HOST_MBX_FULL; // check if mailbox to DEV is free if(((bHostFlags ^ dev->bMyDevFlags) & DEVACK_FLAG) == 0x00 ) dev->bWriteMsgFlag = DEVICE_MBX_EMPTY; // ACK-bit DEV == COM-bit PC --> MBX emty // check if IO state equal or not equal if(((bHostFlags ^ dev->bMyDevFlags) & PDACK_FLAG) == 0x00 ) dev->bExIOFlag = EXCHGIO_EQUAL; // ACK-bit DEV == COM-bit HOST else dev->bExIOFlag = EXCHGIO_NOT_EQUAL; // ACK-bit DEV != COM-bit HOST // check for State if(((bHostFlags ^ dev->bMyDevFlags) & STATEACK_FLAG) == 0x00 ) dev->bStateFlag = STATE_ERR_NON; // ACK-bit DEV == COM-bit PC --> No error else dev->bStateFlag = STATE_ERR; // ACK-bit DEV == COM-bit PC --> No error } /* endif */ //-------------------------------- // Check application //-------------------------------- // application must be logged in if (dev->usOpenCounter > 0) { //****************************************************************** // check for read data //****************************************************************** if((dev->bReadState == TRUE) && (dev->bReadMsgFlag != HOST_MBX_EMPTY)) { // Applikation is waiting on read service, MSG is available dev->tStateInfo.ReadState = STATE_IN_IRQ; switch (dev->bReadMsgFlag) { case HOST_MBX_EMPTY: break; // MBX is empty case HOST_MBX_SYSERR: // System ERROR dev->bReadState = FALSE; set_flag(dev->pReadSemaphore); break; case HOST_MBX_FULL: // Message available dev->bReadState = FALSE; set_flag(dev->pReadSemaphore); break; } } //****************************************************************** // check for write data //****************************************************************** if((dev->bWriteState == TRUE) && (dev->bWriteMsgFlag == DEVICE_MBX_EMPTY)) { dev->tStateInfo.WriteState = STATE_IN_IRQ; dev->bWriteState = FALSE; set_flag(dev->pWriteSemaphore); } //****************************************************************** // check for EXCHGIO state //****************************************************************** if(dev->bExIOEqState == TRUE && dev->bExIOFlag == EXCHGIO_EQUAL) { dev->bExIOEqState = FALSE; set_flag(dev->pExIOSemaphore); } if(dev->bExIONeqState == TRUE && dev->bExIOFlag == EXCHGIO_NOT_EQUAL) { dev->bExIONeqState = FALSE; set_flag(dev->pExIOSemaphore); } //****************************************************************** // check for COM state //****************************************************************** if(dev->bCOMEqState == TRUE && (dev->bHostFlags&COM_FLAG_RDY) == 0) { dev->bCOMEqState = FALSE; set_flag(dev->pInitSemaphore); } if ( dev->bCOMNeqState == TRUE && (dev->bHostFlags & COM_FLAG_RDY) != 0) { dev->bCOMNeqState = FALSE; set_flag(dev->pInitSemaphore); } //****************************************************************** // check for init state //****************************************************************** if(dev->bInitState == TRUE && dev->bInitMsgFlag != INI_MSG_WAIT) { dev->bInitState = FALSE; set_flag(dev->pInitSemaphore); } } printf("H %u ", bHostFlags); printf("D %u ", *(dev->pbDevFlags)); printf("M %u\n", dev->bMyDevFlags); // spin_unlock (&dev->mutex); outp(0xA0,0x20); outp(0x20,0x20); } // pick the device DEV_INSTANCE *cif_dev_get_at(unsigned short n) { DEV_INSTANCE *dev = cif_devices; if(n >= cif_nr_devs) dev = NULL; else while (n--) dev = (DEV_INSTANCE *)dev->next; return dev; } // ================================================================================= // Function: cif_set_irq_state // Enabable /Disable interrupt for PCI cards // --------------------------------------------------------------------------------------- // Input : DeviceObject - // Output : - // Return : - // ================================================================================= void cif_set_irq_state( unsigned short usIntState, DEV_INSTANCE *dev) { unsigned char bData; if(dev && (dev->ucBusType == BUS_TYPE_PCI) ) if ( dev->usBoardIrq != 0 ) { bData=dev->IrqCtrlRegAddr[PCI_INTCTRLSTS_REG]; if(usIntState==HW_INTERRUPT_ENABLE) bData=(unsigned char)(bData|HW_INTERRUPT_ENABLE); else bData=(unsigned char)(bData & ~HW_INTERRUPT_ENABLE); dev->IrqCtrlRegAddr[PCI_INTCTRLSTS_REG]=bData; } } //************************************************************************* //* cif_test_rdy_flag * //* read DEV 'RDY' flag status * //* --------------------------------------------------------------------- * //* Input : ptGlobalDrv - pointer to global DRV structure * //* Output : - * //* Return : TRUE - Hardware check passed * //* FALSE - Hardware check failed * //************************************************************************* unsigned short cif_test_rdy_flag( DEV_INSTANCE * ptDevInst, unsigned short * usRcsError) { unsigned short usRet = FALSE; *usRcsError = 0; // clear RCS error // test RDY flag in DEV HostFlags if((*(ptDevInst->pbHostFlags) & INI_MSG_RDY) == 0) { // RDY flag not set, read RCS error byte if((*usRcsError=(unsigned short)ptDevInst->ptDpmAddress->tRcsInfo.RcsError)>=250) { *usRcsError = 0; ptDevInst->usSpecialRcsError = TRUE; usRet = TRUE; } else { ptDevInst->usSpecialRcsError = FALSE; *usRcsError = (unsigned short)ptDevInst->ptDpmAddress->tRcsInfo.RcsError; *usRcsError += DRV_RCS_ERROR_OFFSET; } } else usRet = TRUE; // RDY flag is set return usRet; } //************************************************************************* //* cif_test_dpm_size * //* compare the DPM size with the configuration * //* --------------------------------------------------------------------- * //* Input : ptDevInst - pointer to DEV instance * //* Output : - * //* Return : TRUE - Watchdog check passed * //* FALSE - Watchdog check failed * //************************************************************************* unsigned short cif_test_dpm_size( DEV_INSTANCE * ptDevInst) { unsigned short usCifEntry; unsigned short usRet = FALSE; // Compare DPM size from the board with the configuration // Allow 1 KByte entry in CIF board // If BOOTSTRAPLOADER is running, this will show always DPMSize = 1, // so use the size which is konfigured ! // Check if BOOTSTRAPLOADER is running if ( (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[0] == 'B') && (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[1] == 'o') && (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[2] == 'o') && (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[3] == 't') && (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[4] == 's') && (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[5] == 't') && (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[6] == 'r') && (ptDevInst->ptDpmAddress->tFiwInfo.FirmwareName[7] == 'a') ) { // This is the BOOTSTRAPLOADER, use DPMSize like configured usRet = TRUE; } else if((usCifEntry = (unsigned short)(ptDevInst->ptDpmAddress->tDevInfo.DpmSize))== 1) { if(ptDevInst->ulDPMSize==2) usRet=TRUE; // Allow a DPMSize configuration of 2 KByte } else if(ptDevInst->ulDPMSize==(unsigned long)(ptDevInst->ptDpmAddress->tDevInfo.DpmSize) ) usRet = TRUE; // DPM size is equal to the configuration return usRet; } //************************************************************************* //* cif_test_dpm_access * //* read and write DEV identifier in the DEV DPM * //* --------------------------------------------------------------------- * //* Input : ptGlobalDrv - pointer to global DRV structure * //* Output : - * //* Return : TRUE - Hardware check passed * //* FALSE - Hardware check failed * //************************************************************************* unsigned short cif_test_dpm_access( DEV_INSTANCE * ptDevInst) { unsigned char abOrgIdentifier[DEVNAMELEN]; unsigned char abTestString [DEVNAMELEN]; unsigned short usIdx = 0, usIdFound = 0, usRet = 0; // eprintf(GRAY_,"DPM_ACCESS %x - %x",ptDevInst->ptDpmAddress,ptDevInst->ptDpmAddress->tDevInfo.DevIdentifier); memcpy(abOrgIdentifier, ptDevInst->ptDpmAddress->tDevInfo.DevIdentifier, DEVNAMELEN); // printf("Dev. Identifier: %.3s\n", ptDevInst->ptDpmAddress->tDevInfo.DevIdentifier); for(usIdx=0,usIdFound=FALSE;(usIdxptDpmAddress->tDevInfo.DevIdentifier,abTestDPM, DEV_IDENTIFIER_LEN); // read test identifier memcpy(abTestString,ptDevInst->ptDpmAddress->tDevInfo.DevIdentifier,DEVNAMELEN); if((abTestString[0]!=abTestDPM[0])|| (abTestString[1] != abTestDPM[1])|| (abTestString[2] != abTestDPM[2])) usRet = FALSE; // Can't write test identifier else { // test identifiere is OK, write orignal identifier to dev DPM memcpy(ptDevInst->ptDpmAddress->tDevInfo.DevIdentifier,abOrgIdentifier, DEV_IDENTIFIER_LEN); // read original identifier memcpy(abTestString,ptDevInst->ptDpmAddress->tDevInfo.DevIdentifier, DEVNAMELEN); if((abTestString[0]!=abOrgIdentifier[0])|| (abTestString[1] != abOrgIdentifier[1])|| (abTestString[2] != abOrgIdentifier[2])) usRet = FALSE; // Can't write original identifier else usRet = TRUE; } } return usRet; } //************************************************************************* //* cif_test_hardware * //* test that the DEV hardware is present and all things well * //* - DEV DPM is accessable and DEV board is really at this address * //* - RDY-Flags of the DEV present * //* ----------------------------------------------------------------------* //* Input : ptGlobalDrv - pointer to global DRV structure * //* Output : - * //* Return : TRUE - Hardware check OK * //* FALSE - Hardware check failed * //************************************************************************* void cif_test_hardware( DEV_INSTANCE * ptDevInst) { // eprintf(GRAY_,"Test Hardware"); ptDevInst->sDrvInitError = 0; // clear driver error if(cif_test_dpm_access( ptDevInst)==FALSE) ptDevInst->sDrvInitError = DRV_DEV_DPM_ACCESS_ERROR; // eprintf(GRAY_,"TEST_DPM_ACCESS"); if(cif_test_rdy_flag(ptDevInst, &(ptDevInst->usRcsError))==FALSE) ptDevInst->sDrvInitError = DRV_DEV_NOT_READY; // eprintf(GRAY_,"TEST_RDY_FLAG"); if(cif_test_dpm_size( ptDevInst)==FALSE) ptDevInst->sDrvInitError = DRV_DEV_DPMSIZE_MISMATCH; // eprintf(GRAY_,"TEST_DPM_SIZE"); } // ================================================================================= // Function: cif_check_hardware // test that the DEV hardware entries during the test at driver startup // --------------------------------------------------------------------------------------- // Input : ptGlobalDrv - pointer to global DRV structure // Output : - // Return : TRUE - Hardware check OK // FALSE - Hardware check failed // ================================================================================= unsigned short cif_check_hardware( DEV_INSTANCE * ptDevInst) { unsigned short usRet = FALSE; // board is successfully initialized if ( ptDevInst->bActive != TRUE) // test on errors { ptDevInst->sDrvInitError = DRV_BOARD_NOT_INITIALIZED; usRet = FALSE; } else if ( ptDevInst->sDrvInitError != DRV_NO_ERROR) { usRet = FALSE; } else if ( ptDevInst->usRcsError != DRV_NO_ERROR) { usRet = FALSE; } else usRet = TRUE; return usRet; } // ================================================================================= // Function: cif_test_com // test the device COM flag // --------------------------------------------------------------------------------------- // Input : dev - pointer to device instance // Output : - // Return : FALSE = COM flag not set // TRUE = COM flag set // ================================================================================= unsigned short cif_test_com( DEV_INSTANCE * dev) { if (dev->usBoardIrq != 0) { if(dev->bHostFlags & COM_FLAG_RDY) return (TRUE); else return (FALSE); } else if ( (*(dev->pbHostFlags) & COM_FLAG_RDY)) return (TRUE); else return (FALSE); } // ================================================================================= // Function: cif_test_ready // test if device is ready // --------------------------------------------------------------------------------------- // Input : dev - pointer to device instance // Output : - // Return : FALSE = device not ready // TRUE = device ready // ================================================================================= unsigned short cif_test_ready( DEV_INSTANCE * dev) { if(dev->usBoardIrq!=0) { // interrupt is running, do not read the flags from the DPM if((dev->usSpecialRcsError==TRUE)&&((dev->bInitMsgFlag & INI_MSG_RDY)==0)) return (TRUE); if ( dev->bInitMsgFlag & INI_MSG_RDY) return (TRUE); else return (FALSE); } else { if((dev->usSpecialRcsError==TRUE)&&((*(dev->pbHostFlags) & INI_MSG_RDY)==0)) return (TRUE); if((*(dev->pbHostFlags) & INI_MSG_RDY)) return (TRUE); else return (FALSE); } } // ================================================================================= // Function: cif_get_devMBXinfo // returns the state of the send mailbox // --------------------------------------------------------------------------------------- // Input : dev - pointer to device instance // Output : - // Return : 0 = DEVICE_MBX_EMPTY // 1 = DEVICE_MBX_FULL // ================================================================================= */ unsigned short cif_get_devMBXinfo( DEV_INSTANCE * dev) { if(dev->usBoardIrq==0) { // polling mode if ( ((*(dev->pbHostFlags) ^ *(dev->pbDevFlags)) & DEVCOM_FLAG) == 0x00) dev->bWriteMsgFlag = DEVICE_MBX_EMPTY; else dev->bWriteMsgFlag = DEVICE_MBX_FULL; } // return actual state, interrupt will set this flag also ! return ((unsigned short)dev->bWriteMsgFlag); } // ================================================================================= // Function: cif_get_hostMBXinfo // returns the state of the send mailbox // --------------------------------------------------------------------------------------- // Input : dev - pointer to device instance // Output : - // Return : 0 = HOST_MBX_EMPTY // 1 = HOST_MBX_FULL // ================================================================================= */ unsigned short cif_get_hostMBXinfo( DEV_INSTANCE * dev) { if (dev->usBoardIrq == 0) { // polling mode if ( ((*(dev->pbHostFlags) ^ *(dev->pbDevFlags)) & HOSTACK_FLAG) == 0x00) dev->bReadMsgFlag = HOST_MBX_EMPTY; else dev->bReadMsgFlag = HOST_MBX_FULL; } // return actual state, interrupt will set this flag also ! return ((unsigned short)dev->bReadMsgFlag); } // ================================================================================= // Function: cif_clear_host_state // --------------------------------------------------------------------------------------- // Input : - // Output : - // Return : - // ================================================================================= void cif_clear_host_state(DEV_INSTANCE * dev) { if ( dev->usBoardIrq != 0) dev->bMyDevFlags &= (~NOTREADY_FLAG); else dev->bMyDevFlags = (unsigned char)(*(dev->pbDevFlags) & (~NOTREADY_FLAG)); *(dev->pbDevFlags) = dev->bMyDevFlags; } // ================================================================================= // Function: cif_set_host_state // --------------------------------------------------------------------------------------- // Input : - // Output : - // Return : - // ================================================================================= void cif_set_host_state(DEV_INSTANCE * dev) { if ( dev->usBoardIrq != 0) dev->bMyDevFlags |= NOTREADY_FLAG; else dev->bMyDevFlags = (unsigned char)(*(dev->pbDevFlags) | NOTREADY_FLAG); *(dev->pbDevFlags) = dev->bMyDevFlags; } // ================================================================================= // Function: cif_boot_start // Device boot start // --------------------------------------------------------------------------------------- // Input : - // Output : - // Return : - // ================================================================================= void cif_boot_start( DEV_INSTANCE * dev) { /* write WStart-Bit in DevFlags */ dev->bMyDevFlags |= (RESET_FLAG | INIT_FLAG); *(dev->pbDevFlags) = dev->bMyDevFlags; } // ================================================================================= // Function: cif_cold_start // Device cold start // --------------------------------------------------------------------------------------- // Input : - // Output : - // Return : - // ================================================================================= void cif_cold_start( DEV_INSTANCE * dev) { dev->bMyDevFlags |= RESET_FLAG; *(dev->pbDevFlags) = dev->bMyDevFlags; } // ================================================================================= // Function: cif_warm_start // Device warm start // --------------------------------------------------------------------------------------- // Input : - // Output : - // Return : - // ================================================================================= void cif_warm_start( DEV_INSTANCE * dev) { /* write warm startm bit in DevFlags */ dev->bMyDevFlags |= INIT_FLAG; *(dev->pbDevFlags) = dev->bMyDevFlags; } // ================================================================================= // Function: cif_send_msg // Signal new message in DEV mailbox is available // --------------------------------------------------------------------------------------- // Input : - // Output : - // Return : - // ================================================================================= */ void cif_send_msg( DEV_INSTANCE * dev) { dev->bWriteMsgFlag = DEVICE_MBX_FULL; if(dev->usBoardIrq != 0) dev->bMyDevFlags ^= DEVCOM_FLAG; else dev->bMyDevFlags = (unsigned char)(*(dev->pbDevFlags) ^ DEVCOM_FLAG); *(dev->pbDevFlags) = dev->bMyDevFlags; } // ================================================================================= // Function: cif_quit_msg // Signal message is read from the PC // --------------------------------------------------------------------------------------- // Input : - // Output : - // Return : - // ================================================================================= */ void cif_quit_msg( DEV_INSTANCE * dev) { dev->bReadMsgFlag = HOST_MBX_EMPTY; if(dev->usBoardIrq != 0) dev->bMyDevFlags ^= HOSTACK_FLAG; // interrupt mode else dev->bMyDevFlags = (unsigned char)(*(dev->pbDevFlags) ^ HOSTACK_FLAG); // polling mode *(dev->pbDevFlags) = dev->bMyDevFlags; } unsigned short jiffies() { unsigned short ret; union REGS pregs; pregs.h.ah=0; int386(0x1A, &pregs, &pregs); ret=pregs.w.cx; ret=ret<<16; ret=pregs.w.dx; return(ret); } long ms_to_jiffies( unsigned long ulTimeout) { return((long)((ulTimeout*HZ)/1000)); } //*********************************************************************** //* Function: cif_wait_com * //* waits for the COM bit * //* Input : dev - pointer to device instance * //* ulTimeout - Timeout * //* Output : - * //* Return : FALSE = Timeout * //* TRUE = No Timeout * //*********************************************************************** unsigned short cif_wait_com(DEV_INSTANCE * dev, unsigned long ulTimeout) //???? { long rtimeout = 0; // rest timeout from interruptible_sleep_on_timeout( ... ); long timeout = ms_to_jiffies( ulTimeout); unsigned long expire = 0; unsigned short usRet = FALSE; if(dev->usBoardIrq != 0) { // interrupt is active //rtimeout=interruptible_sleep_on_timeout( &(dev->pInitSemaphore), timeout); // see .../kernel/sched.h rtimeout=clear_flag_wait_set(dev->pInitSemaphore, timeout); if (!rtimeout) usRet = FALSE; else usRet = TRUE; } else { // poll function expire = timeout+jiffies(); if(dev->bCOMNeqState==TRUE) // wait for COM bit is set (not equal) { while( (((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & COM_FLAG_RDY)==0x00) &&(jiffies() <= expire)) if(T_Shedule) schedule(); else t_delay(1); if( ((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & COM_FLAG_RDY)==0x00 ) usRet=FALSE; else usRet = TRUE; } else // wait for COM bit is clear { while( (((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & COM_FLAG_RDY)!=0x00) && (jiffies() <= expire)) if(T_Shedule) schedule(); else t_delay(1); if( ((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & COM_FLAG_RDY)!=0x00 ) usRet=FALSE; else usRet = TRUE; } } return usRet; } //*********************************************************************** //* Function: cif_wait_reset * //* returns the state of the send mailbox * //* Input : dev - pointer to device instance * //* Output : - * //* Return : FALSE = Timeout * //* TRUE = No Timeout * //*********************************************************************** unsigned short cif_wait_reset( DEV_INSTANCE * dev, unsigned long ulTimeout) { long timeout = ms_to_jiffies( ulTimeout); long rtimeout = 0; unsigned long expire = 0; unsigned short usRet = TRUE; expire = timeout + jiffies(); if (dev->usBoardIrq !=0) { // interrupt function // wait for reset is active, DevFlags == 0 while( ((*(dev->pbDevFlags) & (INIT_FLAG | RESET_FLAG)) != 0x00) &&(jiffies() <= expire ) ) if(T_Shedule) schedule(); else t_delay(1); if( (*(dev->pbDevFlags) & (INIT_FLAG | RESET_FLAG)) != 0x00 ) usRet = FALSE; // timeout else { // rtimeout = interruptible_sleep_on_timeout( &(dev->pInitSemaphore), timeout); rtimeout=clear_flag_wait_set(dev->pInitSemaphore, timeout); if(!rtimeout) usRet = FALSE; else usRet = TRUE; } } else { // poll function // wait for reset is active, DevFlags == 0 while( ((*(dev->pbDevFlags) & (INIT_FLAG | RESET_FLAG)) != 0x00) &&(jiffies() <= expire) ) if(T_Shedule) schedule(); else t_delay(1); if( (*(dev->pbDevFlags) & (INIT_FLAG | RESET_FLAG)) != 0x00 ) usRet = FALSE; else { // wait for RDY is set expire = jiffies() + timeout; while( ((*(dev->pbHostFlags) & INI_MSG_RDY) == 0x00) &&(jiffies() <= expire) ) if(T_Shedule) schedule(); else t_delay(1); if( (*(dev->pbHostFlags) & INI_MSG_RDY) == 0x00 ) usRet = FALSE; // timeout } // update bInitMsgFlag from DPM, like in interrupt dev->bMyDevFlags = *(dev->pbDevFlags); dev->bInitMsgFlag = (unsigned char) (*(dev->pbHostFlags) & INI_MSG_RDYRUN); } return usRet; } //*********************************************************************** //* Function: cif_wait_put_msg * //* wait function for PutMessage * //* Input : dev - pointer to device instance * //* ulTimeout - Timeout * //* Output : - * //* Return : FALSE = timeout * //* TRUE = no timeout * //*********************************************************************** unsigned short cif_wait_put_msg( DEV_INSTANCE * dev, unsigned long ulTimeout) { long timeout = ms_to_jiffies( ulTimeout); unsigned long expire = 0; unsigned short usRet = FALSE; if (dev->usBoardIrq != 0) { // wait timeout, FALSE == timeout // interruptible_sleep_on_timeout( &(dev->pWriteSemaphore), timeout); clear_flag_wait_set(dev->pWriteSemaphore, timeout); if( dev->bWriteMsgFlag == DEVICE_MBX_EMPTY) usRet = TRUE; } else { // wait for mailbox is empty expire = timeout + jiffies(); while( (((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & DEVACK_FLAG) != 0x00) && (jiffies() <= expire ) ) if(T_Shedule) schedule(); else t_delay(1); if( ((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & DEVACK_FLAG) != 0x00 ) usRet = FALSE; // timeout else usRet = TRUE; // no timeout } return usRet; } //*********************************************************************** //* Function: cif_wait_get_msg * //* wait function for GetMessage * //* Input : dev - pointer to device instance * //* ulTimeout - Timeout * //* Output : - * //* Return : FALSE = Timeout * //* TRUE = No Timeout * //*********************************************************************** unsigned short cif_wait_get_msg( DEV_INSTANCE * dev, unsigned long ulTimeout) { long timeout = ms_to_jiffies( ulTimeout); unsigned long expire = 0; unsigned short usRet = FALSE; if (dev->usBoardIrq != 0) { // No Message available, wait for Message // wait timeout, FALSE == timeout // interruptible_sleep_on_timeout( &(dev->pReadSemaphore), timeout); clear_flag_wait_set(dev->pReadSemaphore, timeout); if( dev->bReadMsgFlag == HOST_MBX_FULL) usRet = TRUE; } else { // wait for message is available expire = timeout + jiffies(); while( (((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & HOSTCOM_FLAG) == 0x00) && (jiffies() <= expire) ) if(T_Shedule) schedule(); else t_delay(1); if( ((*(dev->pbHostFlags)^ *(dev->pbDevFlags)) & HOSTCOM_FLAG) == 0x00 ) usRet = FALSE; // timeout else usRet = TRUE; // no timeout } return usRet; } //************************************************************************* //* cif_drv_load() * //* Device Driver Load * //* Input : * //* Output : * //* Return : bSuccess TRUE - at least one board is initialized * //* FALSE - no board is initialized * //************************************************************************* int cif_drv_load (void) { // int result = 0; char k,k1; int bSuccess = 0; // no board available unsigned short usIdx = 0; DEV_INSTANCE * dev = NULL; _dpmi_paddr i_addr; if(cif_nr_devs > 0) { for ( usIdx = 0; usIdx < cif_nr_devs/*CIF_MAX_BOARDS*/; usIdx++) { dev=cif_dev_get_at(usIdx); if(dev->bActive == TRUE) { // eprintf(GRAY_,"Drv load"); dev->pDpmBase=dev->ulBoardAddress; dev->ptDpmAddress=dev->ulBoardAddress+dev->ulDPMByteSize-1024; if(dpmi_map_physical(dev->ptDpmAddress,1024,(unsigned long *)&dev->ptDpmAddress)) dev->bActive=FALSE; dev->pbDpmSendArea=dev->ulBoardAddress; // eprintf(GRAY_,"Drv map1 %d",dev->bActive); if(dpmi_map_physical(dev->pbDpmSendArea,(dev->ulDPMByteSize - 1024)/2,(unsigned long *)&dev->pbDpmSendArea)) dev->bActive=FALSE; dev->pbDpmReceiveArea=dev->ulBoardAddress+(dev->ulDPMByteSize - 1024)/2; // eprintf(GRAY_,"Drv map2 %d",dev->bActive); if(dpmi_map_physical(dev->pbDpmReceiveArea,(dev->ulDPMByteSize - 1024)/2,(unsigned long *)&dev->pbDpmReceiveArea)) dev->bActive=FALSE; // all parameters successfully read. Initialize instance No. usIdx dev->usRcsError = 0; // RCS-Error during startup dev->sDrvInitError = 0; // DRV-Error during startup // pointers to the DEV dpm cells dev->pbHostFlags = &(dev->ptDpmAddress->HostFlags); dev->pbDevFlags = &(dev->ptDpmAddress->DevFlags); // initialize start states dev->usOpenCounter = 0; dev->bInitMsgFlag = INI_MSG_WAIT; // Init state dev->bReadMsgFlag = HOST_MBX_EMPTY; // Read state dev->bWriteMsgFlag = DEVICE_MBX_EMPTY; // write state dev->bExIOFlag = EXCHGIO_NON; // IO state dev->bStateFlag = STATE_ERR_NON; // State field // eprintf(GRAY_,"Drv map3 %d",dev->bActive); dev->pInitSemaphore=create_flag(NULL,"CIFInSem"); dev->pReadSemaphore=create_flag(NULL,"CIFRdSem"); dev->pWriteSemaphore=create_flag(NULL,"CIFWrSem"); dev->pExIOSemaphore=create_flag(NULL,"CIFExIOSem"); // eprintf(GRAY_,"Create Semafore"); // OldIRQ = DPMI_getvect(0x0A); // request IRQ, register interrupt handler and BHs if (dev->usBoardIrq != 0) { i_addr.offset32=cif_interrupt; i_addr.selector=get_CS(); // eprintf(GRAY_,"Get IRQ %d",dev->usBoardIrq); if(!dpmi_setvect(0x68+dev->usBoardIrq,&i_addr)) { k1=1; k=inp(0xA1); k1<<=(10-8); outp(0xA1,k&(k1^0xFF)); if(dev->ucBusType==BUS_TYPE_PCI) cif_set_irq_state(HW_INTERRUPT_ENABLE, dev); // eprintf(GRAY_,"Get IRQ OK"); } } cif_test_hardware( dev); // virtual board address is allocated // printf("V-IRQ = %p \n", dev->pvVirtualIrq ); // printf("V-DPM base address = %p \n", dev->pDpmBase ); // printf("V-DPM send area address = %p \n", dev->pbDpmSendArea); // printf("V-DPM recive area address = %p \n", dev->pbDpmReceiveArea); // printf("V-DPM last kByte = %p \n", dev->ptDpmAddress); // printf("Initialisation OK\n"); // one board is initialized bSuccess = 1; } } // end for } if(!bSuccess) { dpmi_free_map_physical(dev->ptDpmAddress); dpmi_free_map_physical(dev->pbDpmReceiveArea); dpmi_free_map_physical(dev->pbDpmSendArea); } return bSuccess; } //************************************************************************* //* cif_drv_unload * //* Device Driver Unload * //************************************************************************* BOOL cif_drv_unload (void) { DEV_INSTANCE * dev = cif_devices; while(dev) { // deallocate memory, free irq if(dev->usBoardIrq) { cif_set_irq_state( HW_INTERRUPT_DISABLE, dev); // free_irq( (unsigned int)(dev->usBoardIrq), dev); } if((dev->bActive==TRUE) && (dev->pDpmBase!=NULL)) { dpmi_free_map_physical( dev->ptDpmAddress); dpmi_free_map_physical( dev->pbDpmReceiveArea); dpmi_free_map_physical( dev->pbDpmSendArea); } dev = (DEV_INSTANCE *)dev->next; } return (TRUE); // always TRUE if driver is static } // ================================================================================= // Function: cif_get_msg_status // --------------------------------------------------------------------------------------- // Input : dev - pointer to DEV_INSTANCE // Output : - // Return : - // ================================================================================= void cif_get_msg_status( DEV_INSTANCE * dev, unsigned char InByte) { dev->bHostFlags = InByte; // only for information dev->tStateInfo.IRQCnt++; // increment irq counter if((InByte & INI_MSG_RDY) == 0x00) { /* Reset on DEV is running */ dev->bMyDevFlags = 0x00; dev->bReadMsgFlag = HOST_MBX_EMPTY; dev->bWriteMsgFlag = DEVICE_MBX_FULL; dev->bInitMsgFlag = INI_MSG_WAIT; dev->bExIOFlag = EXCHGIO_NON; dev->bStateFlag = STATE_ERR_NON; } else { if(dev->bInitMsgFlag == INI_MSG_WAIT) { // get actual init state dev->bInitMsgFlag = (unsigned char)(InByte & INI_MSG_RDYRUN); } // check if message is available if(((InByte^dev->bMyDevFlags) & HOSTCOM_FLAG) != 0x00) dev->bReadMsgFlag = HOST_MBX_FULL; /* ACK-bit DEV != COM-bit PC --> message inside */ // check if mailbox to DEV is free if(((InByte ^ dev->bMyDevFlags) & DEVACK_FLAG)== 0x00) dev->bWriteMsgFlag = DEVICE_MBX_EMPTY; /* ACK-bit DEV == COM-bit PC --> MBX emty */ // check if IO state equal or not equal if(((InByte ^ dev->bMyDevFlags) & PDACK_FLAG) == 0x00) dev->bExIOFlag = EXCHGIO_EQUAL; /* ACK-bit DEV == COM-bit HOST */ else dev->bExIOFlag = EXCHGIO_NOT_EQUAL; /* ACK-bit DEV != COM-bit HOST */ // check for State if(((InByte ^ dev->bMyDevFlags) & STATEACK_FLAG) == 0x00 ) dev->bStateFlag = STATE_ERR_NON; /* ACK-bit DEV == COM-bit PC --> No error */ else dev->bStateFlag = STATE_ERR; /* ACK-bit DEV == COM-bit PC --> No error */ } /* endif */ // application must be logged in if (dev->usOpenCounter > 0) { //****************************************************************** // check for read data //****************************************************************** if((dev->bReadState == TRUE) && (dev->bReadMsgFlag != HOST_MBX_EMPTY)) { // application is waiting // Applikation is waiting on read service, MSG is available dev->tStateInfo.ReadState = STATE_IN_IRQ; switch (dev->bReadMsgFlag) { case HOST_MBX_EMPTY: // MBX is empty /* Nothing to do */ break; case HOST_MBX_SYSERR: // System ERROR dev->bReadState = FALSE; set_flag(dev->pReadSemaphore); break; case HOST_MBX_FULL: /* Message available */ dev->bReadState = FALSE; set_flag(dev->pReadSemaphore); break; } } //****************************************************************** // check for write data //****************************************************************** if ( (dev->bWriteState == TRUE) && (dev->bWriteMsgFlag == DEVICE_MBX_EMPTY) ) { dev->tStateInfo.WriteState = STATE_IN_IRQ; dev->bWriteState = FALSE; set_flag(dev->pWriteSemaphore); } //****************************************************************** // check for EXCHGIO state //****************************************************************** if(dev->bExIOEqState == TRUE) if (dev->bExIOFlag == EXCHGIO_EQUAL) { dev->bExIOEqState = FALSE; set_flag(dev->pExIOSemaphore); } if ( dev->bExIONeqState == TRUE ) if (dev->bExIOFlag == EXCHGIO_NOT_EQUAL) { dev->bExIONeqState = FALSE; set_flag(dev->pExIOSemaphore); } //****************************************************************** // check for COM state //****************************************************************** if(dev->bCOMEqState == TRUE) if((dev->bHostFlags & COM_FLAG_RDY) == 0) { dev->bCOMEqState = FALSE; set_flag(dev->pInitSemaphore); } if(dev->bCOMNeqState == TRUE) if ( (dev->bHostFlags & COM_FLAG_RDY) != 0) { dev->bCOMNeqState = FALSE; set_flag(dev->pInitSemaphore); } //****************************************************************** // check for init state //****************************************************************** if(dev->bInitState == TRUE) if ( dev->bInitMsgFlag != INI_MSG_WAIT) { dev->bInitState = FALSE; set_flag(dev->pInitSemaphore); } } } //*********************************************************************** //*********************************************************************** //** Driver Functions ** //*********************************************************************** //*********************************************************************** int ioctlinitdrv(DEVIO_RESETCMD* tBuffer) { DEV_INSTANCE *dev = NULL; tBuffer->sError = 0; // clear error if(tBuffer->usBoard >= cif_nr_devs ) tBuffer->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev=(DEV_INSTANCE *)cif_dev_get_at(tBuffer->usBoard))==NULL) tBuffer->sError = DRV_BOARD_NOT_INITIALIZED; else { // lets application open if(dev->usOpenCounter==0) { // 1st time INITDRV is called, run hardware test for this board // Reset error -14 is available if(dev->sDrvInitError==DRV_DEV_OS_VERSION_ERROR) dev->sDrvInitError = DRV_NO_ERROR; if(cif_check_hardware(dev)==FALSE) { // hardwaretest failed if (dev->usRcsError!=0) tBuffer->sError = dev->usRcsError; // RCS error ocurred else tBuffer->sError = dev->sDrvInitError; // or real init error } else { // 1st time INITDRV is called cif_get_msg_status( dev,*(dev->pbHostFlags));// read Board state flags dev->bMyDevFlags = *(dev->pbDevFlags); // store actual flags in internal structure // Board is available dev->usOpenCounter++; // add number of logged applications } } // DRV is running else dev->usOpenCounter++; // new application logged in // return DPM size tBuffer->ulDpmSize = (unsigned long)(dev->ptDpmAddress->tDevInfo.DpmSize); // store OpenCount for information display dev->tStateInfo.OpenCnt = dev->usOpenCounter; } // return length of output data return(sizeof(DEVIO_RESETCMD)); } int ioctlexitdrv(DEVIO_EXITCMD *tBuffer) { DEVIO_EXITCMD *pExitCmd; DEV_INSTANCE *dev = NULL; pExitCmd=tBuffer; pExitCmd->sError = 0; // clear error if(pExitCmd->usBoard >= cif_nr_devs) pExitCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev=(DEV_INSTANCE *)cif_dev_get_at( pExitCmd->usBoard))==NULL) pExitCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->usOpenCounter == 0) { pExitCmd->usDrvOpenCount = dev->usOpenCounter; pExitCmd->sError = DRV_BOARD_NOT_INITIALIZED; } else { /* check for open read/write */ if(dev->usOpenCounter==1) { // disable interrupt until we are ready // spin_lock_irqsave ( &dev->mutex, flags); //spin_lock_irq ( &dev->mutex_ioctl); _asm{cli}; if(dev->bReadState==TRUE) { dev->bReadState = FALSE; set_flag(dev->pReadSemaphore); } if(dev->bWriteState==TRUE) { dev->bWriteState=FALSE; set_flag(dev->pWriteSemaphore); } if(dev->bInitState == TRUE) { dev->bInitState = FALSE; set_flag(dev->pInitSemaphore); } if((dev->bExIOEqState == TRUE)||(dev->bExIONeqState==TRUE)) { dev->bInitState = FALSE; set_flag(dev->pInitSemaphore); } if((dev->bCOMEqState == TRUE)||(dev->bCOMNeqState == TRUE)) { dev->bInitState = FALSE; set_flag(dev->pInitSemaphore); } // enable interrupt we are ready // spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; } /* endif */ dev->usOpenCounter--; // Number of applications dev->tStateInfo.OpenCnt = dev->usOpenCounter; // return OpenCounter for application interface pExitCmd->usDrvOpenCount = dev->usOpenCounter; } return(sizeof(DEVIO_EXITCMD)); } int ioctlgetinfo(DEVIO_GETDEVINFOCMD * tBuffer) { int lRet; DEVIO_GETDEVINFOCMD *ptGetInfoCmd,*pvData; DEV_INSTANCE *dev = NULL; pvData=ptGetInfoCmd=tBuffer; ptGetInfoCmd->sError = 0; // clear error // setup length of output datas lRet = sizeof(ptGetInfoCmd->sError); // Board must be installed, then all info functions available if(ptGetInfoCmd->usBoard >= cif_nr_devs) { ptGetInfoCmd->sError = DRV_BOARD_NOT_INITIALIZED; lRet = 0; } else if((dev=(DEV_INSTANCE *)cif_dev_get_at(ptGetInfoCmd->usBoard))==NULL) { ptGetInfoCmd->sError = DRV_BOARD_NOT_INITIALIZED; lRet = 0; } else { //---------------------------------- // all things well lets work //---------------------------------- // read the InfoArea switch ( ptGetInfoCmd->usInfoArea) { case GET_DRIVER_INFO: if (dev->usBoardIrq!=0) { // copy actual state information, interrupt is running dev->tStateInfo.HostFlags = dev->bHostFlags; // only for information dev->tStateInfo.MyDevFlags = dev->bMyDevFlags; // only for information dev->tStateInfo.InitMsgFlag = dev->bInitMsgFlag; // only for information dev->tStateInfo.ReadMsgFlag = dev->bReadMsgFlag; // only for information dev->tStateInfo.WriteMsgFlag = dev->bWriteMsgFlag;// only for information } else { // copy actual state information, polling is activ dev->tStateInfo.HostFlags = *(dev->pbHostFlags); // only for information dev->tStateInfo.MyDevFlags = *(dev->pbDevFlags); // only for information dev->tStateInfo.InitMsgFlag = dev->bInitMsgFlag; // only for information; dev->tStateInfo.ReadMsgFlag = dev->bReadMsgFlag; // only for information; dev->tStateInfo.WriteMsgFlag = dev->bWriteMsgFlag; // only for information; } memcpy((unsigned char *)(pvData->pabInfoData), (unsigned char *)&(dev->tStateInfo), ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; break; // return length of all output data case GET_VERSION_INFO: memcpy((unsigned char *)(pvData->pabInfoData), (unsigned char *)&(dev->ptDpmAddress->tDevVersion), ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; break; // return length of all output data case GET_FIRMWARE_INFO: memcpy((unsigned char *)(pvData->pabInfoData), (unsigned char *)&(dev->ptDpmAddress->tFiwInfo), ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; break; // return length of all output data case GET_TASK_INFO: memcpy((unsigned char *)(pvData->pabInfoData), (unsigned char *)&(dev->ptDpmAddress->tTaskInfo), ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; break; // return length of all output data case GET_RCS_INFO: memcpy((unsigned char *)(pvData->pabInfoData), (unsigned char *)&(dev->ptDpmAddress->tRcsInfo), ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; break; // return length of all output data case GET_DEV_INFO: memcpy((unsigned char *)(pvData->pabInfoData), (unsigned char *)&(dev->ptDpmAddress->tDevInfo), ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; break; case GET_IO_INFO: ptGetInfoCmd->pabInfoData = (unsigned char *)malloc(ptGetInfoCmd->usInfoLen); ((IOINFO *)(ptGetInfoCmd->pabInfoData))->bComBit =(unsigned char)cif_test_com(dev); ((IOINFO *)(ptGetInfoCmd->pabInfoData))->bIOExchangeMode =(unsigned char)((dev->ptDpmAddress->tRcsInfo.DriverType & 0xF0) >> 4); ((IOINFO *)(ptGetInfoCmd->pabInfoData))->ulIOExchangeCnt = dev->tStateInfo.ExIOCnt; memcpy((unsigned char *)(pvData->pabInfoData),(unsigned char *)(ptGetInfoCmd->pabInfoData), ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; free(ptGetInfoCmd->pabInfoData); break; case GET_IO_SEND_DATA: memcpy((unsigned char *)(pvData->pabInfoData), (unsigned char *)dev->pbDpmSendArea, ptGetInfoCmd->usInfoLen); lRet += ptGetInfoCmd->usInfoLen; break; default: // InfoArea unknown ptGetInfoCmd->sError = DRV_PARAMETER_UNKNOWN; lRet = 0; } } return(lRet); } int ioctlsethost(DEVIO_TRIGGERCMD *tBuffer) { DEVIO_TRIGGERCMD *ptGetTriggerCmd; DEV_INSTANCE *dev = NULL; ptGetTriggerCmd=tBuffer; ptGetTriggerCmd->sError = 0; // clear error // at last one application must be init if(ptGetTriggerCmd->usBoard>=cif_nr_devs) ptGetTriggerCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev=(DEV_INSTANCE *)cif_dev_get_at( ptGetTriggerCmd->usBoard))==NULL) ptGetTriggerCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->usOpenCounter==0) ptGetTriggerCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(cif_test_ready(dev)==FALSE) ptGetTriggerCmd->sError = DRV_DEV_NOT_READY; else if((dev->bCOMEqState!=FALSE)||(dev->bCOMNeqState!=FALSE)) ptGetTriggerCmd->sError = DRV_CMD_ACTIVE; else { // clear host ready and wait for COM-bit is set if(ptGetTriggerCmd->usMode==HOST_READY) { // disable interrupt until we are ready // The process context must use spin_lock_irq() because it knows that // interrupts are always enabled while executing the device ioctl() method. //spin_lock_irqsave ( &dev->mutex, flags); //spin_lock_irq ( &dev->mutex_ioctl); _asm{cli}; // clear host ready bit in bDevFlags and write it cif_clear_host_state(dev); // test if COM bit is set if(cif_test_com(dev)==TRUE) { // COM bit is set // enable interrupt we are ready // spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq( &dev->mutex_ioctl); _asm{sti}; } else if ( ptGetTriggerCmd->ulTimeout == 0L ) { // No Timeout, don't wait for the COM-Bit // enable interrupt we are ready //spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq( &dev->mutex_ioctl); _asm{sti}; } else { // we have to wait for the COM-bit dev->bCOMNeqState = TRUE; // enable interrupt we are ready //spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq( &dev->mutex_ioctl); _asm{sti}; if(cif_wait_com(dev, ptGetTriggerCmd->ulTimeout)==FALSE) ptGetTriggerCmd->sError = DRV_DEV_NO_COM_FLAG; dev->bCOMNeqState = FALSE; } } else { // disable interrupt until we are ready //spin_lock_irqsave ( &dev->mutex, flags); //spin_lock_irq ( &dev->mutex_ioctl); _asm{cli}; // set host ready bit in bDevFlags and write it cif_set_host_state(dev); // test if COM bit is clear if(cif_test_com(dev) == FALSE) { // COM bit is clear // enable interrupt we are ready //spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq( &dev->mutex_ioctl); _asm{sti}; } else if(ptGetTriggerCmd->ulTimeout== 0L) { // No Timeout, don't wait for the COM-Bit // enable interrupt we are ready //spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; } else { // we have to wait for COM-bit is clear dev->bCOMEqState = TRUE; // enable interrupt we are ready // spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; if(cif_wait_com( dev, ptGetTriggerCmd->ulTimeout) == FALSE) ptGetTriggerCmd->sError = DRV_DEV_NO_COM_FLAG; } dev->bCOMEqState = FALSE; } } return(sizeof(ptGetTriggerCmd->sError)); } int ioctlgetparameter(DEVIO_GETPARAMETERCMD *tBuffer) { int lRet; DEVIO_GETPARAMETERCMD *pGetParamCmd; DEV_INSTANCE *dev = NULL; pGetParamCmd=tBuffer; pGetParamCmd->sError = 0; // clear error // length of output data lRet = sizeof(pGetParamCmd->sError); if(pGetParamCmd->usBoard >= cif_nr_devs) { pGetParamCmd->sError = DRV_BOARD_NOT_INITIALIZED; lRet = -1; } else if((dev=(DEV_INSTANCE *)cif_dev_get_at(pGetParamCmd->usBoard))==NULL) { pGetParamCmd->sError = DRV_BOARD_NOT_INITIALIZED; lRet = -1; } else if(dev->usOpenCounter==0) { pGetParamCmd->sError = DRV_BOARD_NOT_INITIALIZED; lRet = -1; } else { switch (pGetParamCmd->usTaskParamNum) { case 1: // Task 1 memcpy((unsigned char *)&(pGetParamCmd->TaskParameter[0]), (unsigned char *)&(dev->ptDpmAddress->tKpt1Param), pGetParamCmd->usTaskParamLen); lRet += pGetParamCmd->usTaskParamLen; break; case 2: // Task 2 memcpy((unsigned char *)&(pGetParamCmd->TaskParameter[0]), (unsigned char *)&(dev->ptDpmAddress->tKpt2Param), pGetParamCmd->usTaskParamLen); lRet += pGetParamCmd->usTaskParamLen; break; default: // parameter error pGetParamCmd->sError = DRV_USR_NUMBER_INVALID; lRet = -1; break; } } return(lRet); } int ioctlparameter(DEVIO_PUTPARAMETERCMD *tBuffer) { DEVIO_PUTPARAMETERCMD *pPutParamCmd; DEV_INSTANCE *dev = NULL; pPutParamCmd=tBuffer; pPutParamCmd->sError = 0; // clear error if(pPutParamCmd->usBoard >= cif_nr_devs) pPutParamCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev = (DEV_INSTANCE *)cif_dev_get_at( pPutParamCmd->usBoard))==NULL) pPutParamCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->usOpenCounter==0) pPutParamCmd->sError = DRV_BOARD_NOT_INITIALIZED; else { switch (pPutParamCmd->usTaskParamNum) { case 1: // Task 1 memcpy ( (unsigned char *)&(dev->ptDpmAddress->tKpt1Param), (unsigned char *)&(pPutParamCmd->TaskParameter), pPutParamCmd->usTaskParamLen); break; case 2: // Task 2 memcpy ( (unsigned char *)&(dev->ptDpmAddress->tKpt2Param), (unsigned char *)&(pPutParamCmd->TaskParameter), pPutParamCmd->usTaskParamLen); break; case 3: // Task 3 memcpy ( (unsigned char *)&(dev->ptDpmAddress->tDevMbx), (unsigned char *)&(pPutParamCmd->TaskParameter), pPutParamCmd->usTaskParamLen); break; case 4: // Task 4 memcpy ( (unsigned char *)&(dev->ptDpmAddress->tDevMbx) + sizeof(TASKPARAM), (unsigned char *)&(pPutParamCmd->TaskParameter), pPutParamCmd->usTaskParamLen); break; case 5: // Task 5 memcpy ( (unsigned char *)&(dev->ptDpmAddress->tDevMbx) + ( 2 * sizeof(TASKPARAM)), (unsigned char *)&(pPutParamCmd->TaskParameter), pPutParamCmd->usTaskParamLen); break; case 6: // Task 6 memcpy ( (unsigned char *)&(dev->ptDpmAddress->tDevMbx) + ( 3 * sizeof(TASKPARAM)), (unsigned char *)&(pPutParamCmd->TaskParameter), pPutParamCmd->usTaskParamLen); break; case 7: // Task 7 memcpy ( (unsigned char *)&(dev->ptDpmAddress->tDevMbx) + ( 4 * sizeof(TASKPARAM)), (unsigned char *)&(pPutParamCmd->TaskParameter), pPutParamCmd->usTaskParamLen); break; default: // parameter error pPutParamCmd->sError = DRV_USR_NUMBER_INVALID; break; } } return(sizeof(DEVIO_PUTPARAMETERCMD)); } int ioctlresetdev(DEVIO_RESETCMD *tBuffer) { DEVIO_RESETCMD *pResetCmd; DEV_INSTANCE *dev = NULL; pResetCmd=tBuffer; pResetCmd->sError = 0; // clear error // is DEV board installed an driver activ if(pResetCmd->usBoard >= cif_nr_devs) pResetCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev=(DEV_INSTANCE *)cif_dev_get_at(pResetCmd->usBoard))==NULL) pResetCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->usOpenCounter==0) pResetCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->bInitState!=FALSE) pResetCmd->sError = DRV_CMD_ACTIVE; else { // disable interrupt until we are ready //spin_lock_irqsave ( &dev->mutex, flags); //spin_lock_irq ( &dev->mutex); _asm{cli}; if(pResetCmd->usMode==4) cif_boot_start(dev); // boot else if(pResetCmd->usMode==3) cif_warm_start(dev); // warm boot else cif_cold_start(dev); // cold boot // wait for RDY is gone and init state OK dev->bInitState = TRUE; // start init // enable interrupt we are ready //spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; // Wait for reset is running if(cif_wait_reset(dev, pResetCmd->ulTimeout)==FALSE) pResetCmd->sError = DRV_DEV_RESET_TIMEOUT; else { // No Timeout, test actual state switch ( dev->bInitMsgFlag ) { case INI_MSG_RDYRUN: case INI_MSG_RDY: // Init is ready pResetCmd->sError = DRV_NO_ERROR; break; default: pResetCmd->sError = DRV_INIT_STATE_ERROR; break; } } dev->bInitState = FALSE; // stop init } return(sizeof(DEVIO_RESETCMD)); } int ioctlputmsg(DEVIO_PUTMESSAGECMD *tBuffer) { DEVIO_PUTMESSAGECMD *pPutMsgCmd; DEV_INSTANCE *dev = NULL; pPutMsgCmd=tBuffer; pPutMsgCmd->sError = 0; // Clear error // at last one application must be init if(pPutMsgCmd->usBoard >= cif_nr_devs) pPutMsgCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev=(DEV_INSTANCE *)cif_dev_get_at( pPutMsgCmd->usBoard))==NULL) pPutMsgCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->usOpenCounter == 0) pPutMsgCmd->sError = DRV_BOARD_NOT_INITIALIZED; else { // set driver info data dev->tStateInfo.WriteCnt++; dev->tStateInfo.LastFunction = FKT_WRITE; //----------- (7_04_2002 RomanS) ----------- while(dev->tStateInfo.WriteState==STATE_WAIT) if(T_Shedule) schedule(); else t_delay(1); //------------------------------------------ dev->tStateInfo.WriteState = STATE_IN; if(cif_test_ready(dev)==FALSE) pPutMsgCmd->sError = DRV_DEV_NOT_READY; else if(dev->bWriteState!=FALSE) pPutMsgCmd->sError = DRV_CMD_ACTIVE; else { // spin_lock_irqsave ( &dev->mutex, flags); //spin_lock_irq ( &dev->mutex_ioctl); _asm{cli}; if(cif_get_devMBXinfo(dev)==DEVICE_MBX_EMPTY) // check if mailbox is free { memcpy( (unsigned char *)&(dev->ptDpmAddress->tDevMbx), (unsigned char *)&(pPutMsgCmd->tMsg), (unsigned short)(pPutMsgCmd->tMsg.ln + 8)); cif_send_msg(dev); // spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; } else if (pPutMsgCmd->ulTimeout==0L) { // spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; pPutMsgCmd->sError = DRV_DEV_MAILBOX_FULL; } else // we have to wait for MBX empty { dev->tStateInfo.WriteState = STATE_WAIT; dev->bWriteState = TRUE; // spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; if(cif_wait_put_msg(dev, pPutMsgCmd->ulTimeout)==FALSE) // timeout in Ticks, 1 Tick = 1/TZ msec pPutMsgCmd->sError = DRV_DEV_PUT_TIMEOUT; else { memcpy( (unsigned char *)&(dev->ptDpmAddress->tDevMbx), (unsigned char *)&(pPutMsgCmd->tMsg), (unsigned short)(pPutMsgCmd->tMsg.ln + 8)); // spin_lock_irqsave ( &dev->mutex, flags); //spin_lock_irq ( &dev->mutex_ioctl); _asm{cli}; cif_send_msg(dev); // spin_unlock_irqrestore ( &dev->mutex, flags); //spin_unlock_irq ( &dev->mutex_ioctl); _asm{sti}; } dev->bWriteState = FALSE; } } dev->tStateInfo.WriteState = STATE_OUT; } return(sizeof(DEVIO_PUTMESSAGECMD)); } int ioctlgetmsg(DEVIO_GETMESSAGECMD *tBuffer,unsigned char n_task) { unsigned short usMsgLen; DEVIO_GETMESSAGECMD *pGetMsgCmd; DEV_INSTANCE *dev = NULL; TASK_BOX *t_box= NULL; pGetMsgCmd=tBuffer; pGetMsgCmd->sError = 0; // Clear error // at last one application must be init if(pGetMsgCmd->usBoard >= cif_nr_devs) pGetMsgCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev = (DEV_INSTANCE *)cif_dev_get_at( pGetMsgCmd->usBoard))==NULL) pGetMsgCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->usOpenCounter==0) pGetMsgCmd->sError = DRV_BOARD_NOT_INITIALIZED; else { dev->tStateInfo.ReadCnt++; dev->tStateInfo.LastFunction = FKT_READ; //----------- (7_04_2002 RomanS) ----------- if(dev->tStateInfo.ReadState==STATE_WAIT) { // eprintf(GRAY_,"TEST: GET WAIT %d",n_task); t_box=dev->task_boxes; while(t_box && t_box->n_task!=n_task) t_box=t_box->next; if(!t_box) {pGetMsgCmd->sError = DRV_DEV_NOT_READY; return(sizeof(DEVIO_GETMESSAGECMD)); } if(t_box->n_mesage || pGetMsgCmd->ulTimeout) while(dev->tStateInfo.ReadState==STATE_WAIT) { if(t_box->n_mesage) { usMsgLen=(unsigned short)(t_box->buf.ln + 8); memcpy((unsigned char *)&(pGetMsgCmd->tMsg),(unsigned char *)&(t_box->buf),(unsigned short)usMsgLen); t_box->n_mesage--; return(sizeof(DEVIO_GETMESSAGECMD)); } if(T_Shedule) schedule(); else t_delay(1); } else {pGetMsgCmd->sError = DRV_DEV_GET_NO_MESSAGE; return(sizeof(DEVIO_GETMESSAGECMD));} } //----------------------------------------- dev->tStateInfo.ReadState = FKT_READ; if(cif_test_ready(dev)==FALSE) pGetMsgCmd->sError = DRV_DEV_NOT_READY; else if(dev->bReadState!=FALSE) pGetMsgCmd->sError = DRV_CMD_ACTIVE; else { for(;;) { t_box=dev->task_boxes; while(t_box && t_box->n_task!=n_task) t_box=t_box->next; if(!t_box) {pGetMsgCmd->sError = DRV_DEV_NOT_READY; break; } if(t_box->n_mesage) { usMsgLen=(unsigned short)(t_box->buf.ln + 8); memcpy( (unsigned char *)&(pGetMsgCmd->tMsg), (unsigned char *)&(t_box->buf), (unsigned short)usMsgLen); t_box->n_mesage--; break; } // spin_lock_irqsave ( &dev->mutex, flags); _asm{cli}; if(cif_get_hostMBXinfo(dev)==HOST_MBX_FULL) // no activ service, if a message available, read it { usMsgLen=(unsigned short)(dev->ptDpmAddress->tPcMbx.ln + 8); if(n_task==dev->ptDpmAddress->tPcMbx.nr) { memcpy( (unsigned char *)&(pGetMsgCmd->tMsg), (unsigned char *)&(dev->ptDpmAddress->tPcMbx), (unsigned short)usMsgLen); cif_quit_msg(dev); break; // spin_unlock_irqrestore ( &dev->mutex, flags); _asm{sti}; } else { t_box=dev->task_boxes; while(t_box && t_box->n_task!=dev->ptDpmAddress->tPcMbx.nr) t_box=t_box->next; if(!t_box) { cif_quit_msg(dev); continue; } // {pGetMsgCmd->sError = DRV_DEV_NOT_READY; break; } memcpy ( (unsigned char *)&(t_box->buf), (unsigned char *)&(dev->ptDpmAddress->tPcMbx), (unsigned short)usMsgLen); t_box->n_mesage++; cif_quit_msg(dev); continue; } } else if(pGetMsgCmd->ulTimeout == 0L) { // spin_unlock_irqrestore ( &dev->mutex, flags); _asm{sti}; pGetMsgCmd->sError = DRV_DEV_GET_NO_MESSAGE; break; } else { dev->bReadState = TRUE; dev->tStateInfo.ReadState = STATE_WAIT; // spin_unlock_irqrestore ( &dev->mutex, flags); _asm{sti}; if(cif_wait_get_msg(dev,pGetMsgCmd->ulTimeout)==FALSE) // Timeout in Ticks, 1 Tick = 1/TZ msec { pGetMsgCmd->sError = DRV_DEV_GET_TIMEOUT; dev->bReadState = FALSE; break; } else { usMsgLen = (unsigned short)(dev->ptDpmAddress->tPcMbx.ln + 8); if(n_task==dev->ptDpmAddress->tPcMbx.nr) { memcpy( (unsigned char *)&(pGetMsgCmd->tMsg), (unsigned char *)&(dev->ptDpmAddress->tPcMbx), (unsigned short)usMsgLen); // spin_lock_irqsave ( &dev->mutex, flags); _asm{cli}; cif_quit_msg(dev); dev->bReadState = FALSE; break; // spin_unlock_irqrestore ( &dev->mutex, flags); _asm{sti}; } else { t_box=dev->task_boxes; while(t_box && t_box->n_task!=dev->ptDpmAddress->tPcMbx.nr) t_box=t_box->next; if(!t_box) { cif_quit_msg(dev); dev->bReadState = FALSE; continue; } // {pGetMsgCmd->sError = DRV_DEV_NOT_READY; dev->bReadState = FALSE; break; } memcpy ( (unsigned char *)&(t_box->buf), (unsigned char *)&(dev->ptDpmAddress->tPcMbx), (unsigned short)usMsgLen); t_box->n_mesage++; cif_quit_msg(dev); dev->bReadState = FALSE; continue; } } // dev->bReadState = FALSE; // delete pending action } } } dev->tStateInfo.ReadState = STATE_OUT; } return(sizeof(DEVIO_GETMESSAGECMD)); } int ioctltaskstate(DEVIO_GETTASKSTATECMD *tBuffer) { DEVIO_GETTASKSTATECMD *pGetTskStateCmd; DEV_INSTANCE *dev = NULL; pGetTskStateCmd=tBuffer; pGetTskStateCmd->sError = 0; // clear error // at last one application must be init if(pGetTskStateCmd->ucBoard >= cif_nr_devs) pGetTskStateCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if((dev=(DEV_INSTANCE *)cif_dev_get_at( pGetTskStateCmd->ucBoard))==NULL) pGetTskStateCmd->sError = DRV_BOARD_NOT_INITIALIZED; else if(dev->usOpenCounter==0) pGetTskStateCmd->sError = DRV_BOARD_NOT_INITIALIZED; else { if(pGetTskStateCmd->usStateNum==1) memcpy ( (unsigned char *)&(pGetTskStateCmd->TaskState[0]), (unsigned char *)&(dev->ptDpmAddress->tKpt1State), pGetTskStateCmd->usStateLen); else memcpy ( (unsigned char *)&(pGetTskStateCmd->TaskState[0]), (unsigned char *)&(dev->ptDpmAddress->tKpt2State), pGetTskStateCmd->usStateLen); } return(sizeof(DEVIO_GETTASKSTATECMD)); } //************************************************************************ //************************************************************************ //** API-Functions ** //************************************************************************ //************************************************************************ typedef struct DEV_DPM_SIZEtag { unsigned long ulDpmSize; unsigned long ulDpmIOSize; } DEV_DPM_SIZE; DEV_DPM_SIZE tDevDPMSize[MAX_DEV_BOARDS] = { {0L,0L}, {0L,0L}, {0L,0L}, {0L,0L} }; // DPM size of each board // ================================================================================= // Function: DevInitBoard // initializes a DEV board // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // *pDevAddress - not used // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevInitBoard ( unsigned short usDevNumber) { DEVIO_RESETCMD tBuffer; short sRet = DRV_NO_ERROR; if (usDevNumber >= CIF_NR_DEVS) sRet = DRV_USR_DEV_NUMBER_INVALID; else { // clear all data buffers tBuffer.usBoard = usDevNumber; tBuffer.sError = sRet; if(!ioctlinitdrv(&tBuffer)) sRet = DRV_USR_COMM_ERR; // if ( !ioctl(hDevDrv, CIF_IOCTLINITDRV, &tBuffer) ) sRet = DRV_USR_COMM_ERR; else { sRet = tBuffer.sError; if(sRet == DRV_NO_ERROR) { // Save the DPM size for further function calls and calculate the length // of the DPM-IO data area tDevDPMSize[usDevNumber].ulDpmSize = tBuffer.ulDpmSize; tDevDPMSize[usDevNumber].ulDpmIOSize = ((tBuffer.ulDpmSize * 1024) - 1024) /2; } } } return sRet; } // ================================================================================= // Function: DevExitBoard // closes the connection to a DEV board // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevExitBoard ( unsigned short usDevNumber) { DEVIO_EXITCMD tBuffer; short sRet = DRV_NO_ERROR; if(usDevNumber>=MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else { tBuffer.usBoard = usDevNumber; // if(!ioctl(hDevDrv, CIF_IOCTLEXITDRV, &tBuffer)) sRet = DRV_USR_COMM_ERR; if(!ioctlexitdrv(&tBuffer)) sRet = DRV_USR_COMM_ERR; else sRet = tBuffer.sError; } return sRet; } // ================================================================================= // Function: DevGetInfo // read the differnt information areas from a DEV board // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // usInfoArea - 1..n // usSize - size of the users data buffer // pvData - pointer to users data buffer // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed //================================================================================= short DevGetInfo ( unsigned short usDevNumber, unsigned short usInfoArea, unsigned short usSize, void *pvData) { DEVIO_GETDEVINFOCMD tBuffer; short sRet = DRV_NO_ERROR; // valid handle available, driver is open if(usDevNumber >= CIF_NR_DEVS) sRet = DRV_USR_DEV_NUMBER_INVALID; else if ( usSize == 0) sRet = DRV_USR_SIZE_ZERO; else { // test area spezific data switch ( usInfoArea) { case GET_VERSION_INFO: if(usSize>sizeof(VERSIONINFO)) sRet = DRV_USR_SIZE_TOO_LONG; break; case GET_DRIVER_INFO: if(usSize>sizeof(DRIVERINFO)) sRet = DRV_USR_SIZE_TOO_LONG; break; case GET_FIRMWARE_INFO:if(usSize>sizeof(FIRMWAREINFO))sRet = DRV_USR_SIZE_TOO_LONG; break; case GET_RCS_INFO: if(usSize>sizeof(RCSINFO)) sRet = DRV_USR_SIZE_TOO_LONG; break; case GET_DEV_INFO: if(usSize>sizeof(DEVINFO)) sRet = DRV_USR_SIZE_TOO_LONG; break; case GET_TASK_INFO: if(usSize>sizeof(TASKINFO)) sRet = DRV_USR_SIZE_TOO_LONG; break; case GET_IO_INFO: if(usSize>sizeof(IOINFO)) sRet = DRV_USR_SIZE_TOO_LONG; break; case GET_IO_SEND_DATA: if(usSize>tDevDPMSize[usDevNumber].ulDpmIOSize) sRet = DRV_USR_SIZE_TOO_LONG; break; default: sRet = DRV_USR_INFO_AREA_INVALID; } if(sRet==DRV_NO_ERROR) { // set output buffer tBuffer.usBoard = usDevNumber; tBuffer.usInfoArea = usInfoArea; tBuffer.usInfoLen = usSize; tBuffer.pabInfoData = pvData; // needed in kernel-space to copy data back to it! tBuffer.sError = sRet; // activate function if(!ioctlgetinfo(&tBuffer)) sRet = DRV_USR_COMM_ERR; // if ( !ioctl(hDevDrv, CIF_IOCTLGETINFO, &tBuffer) ) sRet = DRV_USR_COMM_ERR; else sRet = tBuffer.sError; } } return sRet; } // ================================================================================= // Function: DevSetHostState // set the host state // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // usMode - 0 = Host not ready, 1 = Host ready // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevSetHostState ( unsigned short usDevNumber, unsigned short usMode, unsigned long ulTimeout) { DEVIO_TRIGGERCMD tBuffer; short sRet = DRV_NO_ERROR; if ( usDevNumber >= MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else if ( usMode > HOST_READY) sRet = DRV_USR_MODE_INVALID; else { // set output buffer tBuffer.usBoard = usDevNumber; tBuffer.usMode = usMode; tBuffer.ulTimeout = ulTimeout; tBuffer.sError = sRet; if(!ioctlsethost(&tBuffer)) sRet = DRV_USR_COMM_ERR; else sRet = tBuffer.sError; } return sRet; } // ================================================================================= // Function: DevGetTaskParameter // reads the task parameters from task 1 and 2 // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // usArea - 1,2 // usSize - size of the users data buffer // pvData - pointer to users data buffer // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevGetTaskParameter ( unsigned short usDevNumber, unsigned short usNumber, unsigned short usSize, void *pvData) { DEVIO_GETPARAMETERCMD tBuffer; short sRet = DRV_NO_ERROR; if (usDevNumber >= MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else if ((usNumber < 1)||(usNumber > 2)) sRet = DRV_USR_NUMBER_INVALID; else if (usSize == 0) sRet = DRV_USR_SIZE_ZERO; else if (usSize > sizeof(TASKPARAM)) sRet = DRV_USR_SIZE_TOO_LONG; else { // set command buffer tBuffer.usBoard = usDevNumber; tBuffer.usTaskParamNum = usNumber; tBuffer.usTaskParamLen = usSize; //tBuffer.ptTaskParam = pvData; tBuffer.sError = sRet; // activate function // if ( !ioctl(hDevDrv, CIF_IOCTLGETPARAMETER, &tBuffer)) sRet = DRV_USR_COMM_ERR; if (!ioctlgetparameter(&tBuffer)) sRet = DRV_USR_COMM_ERR; else { memcpy ( (unsigned char *)pvData, (unsigned char *)&(tBuffer.TaskParameter), usSize); sRet = tBuffer.sError; } } return sRet; } // ================================================================================= // Function: DevPutTaskParameter // write communication parameters // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // usNumber - number of the parameter area (1..7) // usSize - size of the parameter area ( >0, <= max.Size) // pvData - pointer to task parameter buffer // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevPutTaskParameter ( unsigned short usDevNumber, unsigned short usNumber, unsigned short usSize, void *pvData) { DEVIO_PUTPARAMETERCMD tBuffer; short sRet = DRV_NO_ERROR; if (usDevNumber >= MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else if ((usNumber < 1)||(usNumber > 7)) sRet = DRV_USR_NUMBER_INVALID; else if (usSize == 0) sRet = DRV_USR_SIZE_ZERO; else if ( usSize > sizeof(TASKPARAM)) sRet = DRV_USR_SIZE_TOO_LONG; else { // set command buffer tBuffer.usBoard = usDevNumber; tBuffer.usTaskParamNum = usNumber; tBuffer.usTaskParamLen = usSize; memcpy ((unsigned char *)&(tBuffer.TaskParameter),(unsigned char *)pvData, usSize); tBuffer.sError = sRet; // activate function // if(!ioctl(hDevDrv, CIF_IOCTLPARAMETER, &tBuffer)) sRet = DRV_USR_COMM_ERR; if(!ioctlparameter(&tBuffer)) sRet = DRV_USR_COMM_ERR; else sRet = tBuffer.sError; } return sRet; } // ================================================================================= // Function: DevReset // reset a DEV board // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // usMode - reset mode (2,3) // ulTimeout - function timeout in milliseconds // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevReset ( unsigned char usDevNumber, unsigned short usMode, unsigned long ulTimeout) { DEVIO_RESETCMD tBuffer; short sRet = DRV_NO_ERROR; if(usDevNumber >= MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else if((usMode != COLDSTART) && (usMode != WARMSTART) && (usMode != BOOTSTART)) sRet = DRV_USR_MODE_INVALID; else { // set output buffer tBuffer.usBoard = usDevNumber; tBuffer.usMode = usMode; tBuffer.ulTimeout = ulTimeout; tBuffer.sError = sRet; // if(!ioctl(hDevDrv, CIF_IOCTLRESETDEV, &tBuffer)) sRet = DRV_USR_COMM_ERR; if(!ioctlresetdev(&tBuffer)) sRet = DRV_USR_COMM_ERR; else sRet = tBuffer.sError; } return sRet; } // ================================================================================= // Function: DevPutMessage // send a message to a DEV board // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // ptMessage - pointer to users message // ulTimeout - function timeout in milliseconds // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevPutMessage ( unsigned short usDevNumber, MSG_STRUC *ptMessage, unsigned long ulTimeout) { DEVIO_PUTMESSAGECMD tBuffer; short sRet = DRV_NO_ERROR; // valid handle available, driver is open if(usDevNumber >= MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else { // set output buffer tBuffer.usBoard = usDevNumber; tBuffer.ulTimeout = ulTimeout; memcpy( &tBuffer.tMsg, ptMessage, sizeof(MSG_STRUC)); tBuffer.sError = sRet; // activate function // if(!ioctl(hDevDrv, CIF_IOCTLPUTMSG, &tBuffer)) sRet = DRV_USR_COMM_ERR; if(!ioctlputmsg(&tBuffer)) sRet = DRV_USR_COMM_ERR; else sRet = tBuffer.sError; } return sRet; } // ================================================================================= // Function: DevGetMessage // read a message from a DEV board // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // usSize - size of the users data area (>0..<= sizeof(MSG_STRUC)) // ptMessage - pointer to the users data buffer // ulTimeout - function timeout in milliseconds // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevGetMessage ( unsigned short usDevNumber, unsigned short usSize, MSG_STRUC *ptMessage, unsigned long ulTimeout, unsigned char n_task) { DEVIO_GETMESSAGECMD tBuffer; short sRet = DRV_NO_ERROR; if(usDevNumber >= MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else if(usSize==0 || usSize>sizeof(MSG_STRUC)) sRet = DRV_USR_SIZE_INVALID; else { // set output buffer tBuffer.usBoard = usDevNumber; tBuffer.ulTimeout = ulTimeout; tBuffer.sError = sRet; // activate function // if ( !ioctl(hDevDrv, CIF_IOCTLGETMSG, &tBuffer)) sRet = DRV_USR_COMM_ERR; if (!ioctlgetmsg(&tBuffer,n_task)) sRet = DRV_USR_COMM_ERR; else { memcpy( ptMessage, &tBuffer.tMsg, sizeof(MSG_STRUC)); sRet = tBuffer.sError; } } return sRet; } // ================================================================================= // Function: DevGetTaskState // read a task state field form a DEV board // --------------------------------------------------------------------------------------- // Input : usDevNumber - number of the DEV board (0..3) // usNumber - number of the status field (1,2) // usSize - size of the users data buffer (>0..<= 64) // pvData - pointer to users data buffer // Output : - // Return : DRV_NO_ERROR - function successfull // != DRV_NO_ERROR - function failed // ================================================================================= short DevGetTaskState( unsigned short usDevNumber, unsigned short usNumber, unsigned short usSize, void *pvData) { DEVIO_GETTASKSTATECMD tBuffer; short sRet = DRV_NO_ERROR; if(usDevNumber >= MAX_DEV_BOARDS) sRet = DRV_USR_DEV_NUMBER_INVALID; else if(usNumber < 1 || usNumber > 2 ) sRet = DRV_USR_NUMBER_INVALID; else if(usSize == 0) sRet = DRV_USR_SIZE_ZERO; else if(usSize > sizeof(TASKSTATE) ) sRet = DRV_USR_SIZE_TOO_LONG; else { // set command buffer tBuffer.ucBoard = usDevNumber; tBuffer.usStateNum = usNumber; tBuffer.usStateLen = usSize; //memcpy( tBuffer.TaskState, pvData, usSize); tBuffer.sError = sRet; // activate function // if (!ioctl(hDevDrv, CIF_IOCTLTASKSTATE, &tBuffer)) sRet = DRV_USR_COMM_ERR; if (!ioctltaskstate(&tBuffer)) sRet = DRV_USR_COMM_ERR; else { memcpy( pvData, tBuffer.TaskState, usSize); sRet = tBuffer.sError; } } return sRet; } //************************************************************************* //************************************************************************* //** Global functions ** //************************************************************************* //************************************************************************* unsigned char SendReceiveMessage(unsigned short board, RCS_MESSAGE *ptMsg) { short sRet; if((sRet=DevPutMessage(board,(MSG_STRUC *)ptMsg, 200L))==DRV_NO_ERROR) { if((sRet = DevGetMessage(board,sizeof(RCS_MESSAGE),(MSG_STRUC *)ptMsg, 200L,ptMsg->nr))==DRV_NO_ERROR) return( ptMsg->f ); else return(3); } else return(3); return( 0 ); } //************************************************************************* //* enable_CIF() * //* Search and init CIF * //************************************************************************* DPM_PLC_PARAMETER DPParameter; // Parameters for DP protocolls DPM_DIAGNOSTICS tTaskState; DRIVERINFO tDriverInfo; void enable_CIF() { DDLM_DOWNLOAD_REQUEST *ptDownloadRequest; DPM_BUS_DP *ptBusDpm; RCS_MESSAGE tMsg; int res = 0,i; unsigned char task_opr; for(i=0;i=c_num) return; // scan pci bus for Hilscher boards res=cif_scan_pci(); // eprintf(GRAY_,"Scan Err %d",res); if(cif_nr_devs==0) return; else if(!cif_drv_load()) {cif_nr_devs=0; return;} else { // eprintf(GRAY_,"CIF OK!"); eprintf(GREEN_,"%x CIF50-Board(s) detected\n", res); for(i=0;ibReq_Add = 0; ptDownloadRequest->bArea_Code = DPM_DEVICE_PRM; ptDownloadRequest->usAdd_Offset = 0; ptBusDpm = ( DPM_BUS_DP* )&ptDownloadRequest->abData; ptBusDpm->usBus_Para_Len = sizeof( DPM_BUS_DP ) ; ptBusDpm->bFDL_Add = c_ptr[i].basaddr; ptBusDpm->bBaudrate = c_ptr[i].baud; ptBusDpm->usTSL = par_bus[c_ptr[i].baud].usTSL; //300; ptBusDpm->usMin_TSDR = par_bus[c_ptr[i].baud].usMin_TSDR; //11; ptBusDpm->usMax_TSDR = par_bus[c_ptr[i].baud].usMax_TSDR; //150; ptBusDpm->bTQUI = par_bus[c_ptr[i].baud].bTQUI; //0; ptBusDpm->bTSET = par_bus[c_ptr[i].baud].bTSET; //1; ptBusDpm->ulTTR = par_bus[c_ptr[i].baud].ulTTR; //2021; ptBusDpm->bG = par_bus[c_ptr[i].baud].bG; //10; ptBusDpm->bHSA = 126; ptBusDpm->bMax_Retry_Limit = par_bus[c_ptr[i].baud].bMax_Retry_Limit; //1; ptBusDpm->Bp_Flag.bReserved = 0; ptBusDpm->Bp_Flag.bError_Action_Flag = 0; ptBusDpm->usMin_Slave_Intervall = 0; ptBusDpm->usPoll_Timeout = 10; ptBusDpm->usData_Control_Time = 120; ptBusDpm->bAlarm_Max = 0; ptBusDpm->bMax_User_Global_Control = 0; ptBusDpm->abOctet[0] = 0; ptBusDpm->abOctet[1] = 0; ptBusDpm->abOctet[2] = 0; ptBusDpm->abOctet[3] = 0; tMsg.ln = sizeof(DPM_BUS_DP)+sizeof(DDLM_DOWNLOAD_REQUEST)- DPM_MAX_LEN_DATA_UNIT; SendReceiveMessage(c_ptr[i].nomport,(RCS_MESSAGE*)&tMsg); do { DevGetTaskState(c_ptr[i].nomport,2,sizeof( tTaskState ),&tTaskState); } while(tTaskState.bDPM_state!=OPERATE); CIF_CTR[c_ptr[i].nomport] = c_ptr+i; } } } //************************************************************************* //* RegTaskForCIF() * //* Registr task for CIF * //************************************************************************* int RegTaskForCIF(unsigned short usDevNumber,unsigned char task_n) //int Check_CIF(unsigned short usDevNumber) { DEV_INSTANCE *dev = NULL; TASK_BOX *task; if(usDevNumber >= cif_nr_devs) return(DRV_BOARD_NOT_INITIALIZED); else if((dev = (DEV_INSTANCE *)cif_dev_get_at(usDevNumber))==NULL) return(DRV_BOARD_NOT_INITIALIZED); else if(dev->usOpenCounter==0) return(DRV_BOARD_NOT_INITIALIZED); else { if(!dev->task_boxes) { dev->task_boxes=calloc(sizeof(TASK_BOX),1); dev->task_boxes->n_task=task_n; } else { task=dev->task_boxes; if(task->n_task==task_n) return(DRV_NO_ERROR); while(task->next) { if(task->n_task==task_n) return(DRV_NO_ERROR); task=task->next; } task->next=calloc(sizeof(TASK_BOX),1); task=task->next->n_task=task_n; } } // if(usDevNumber < cif_nr_devs && STAT_CIF[usDevNumber]==0) return(1); return(DRV_NO_ERROR); } //************************************************************************* //* UnregTaskForCIF() * //* Registr task for CIF * //************************************************************************* int UnregTaskForCIF(unsigned short usDevNumber,unsigned char task_n) //int Check_CIF(unsigned short usDevNumber) { DEV_INSTANCE *dev = NULL; TASK_BOX *task; if(usDevNumber >= cif_nr_devs) return(DRV_BOARD_NOT_INITIALIZED); else if((dev = (DEV_INSTANCE *)cif_dev_get_at(usDevNumber))==NULL) return(DRV_BOARD_NOT_INITIALIZED); else if(dev->usOpenCounter==0) return(DRV_BOARD_NOT_INITIALIZED); else if(dev->task_boxes) return(DRV_NO_ERROR); else { if(dev->task_boxes->n_task==task_n) dev->task_boxes=dev->task_boxes->next; task=dev->task_boxes; while(task->next && task->next->n_task!=task_n) task=task->next; if(!task->next) return(DRV_NO_ERROR); task->next=task->next->next; } return(DRV_NO_ERROR); } //************************************************************************* //* disable_CIF() * //* Free CIF memory * //************************************************************************* void disable_CIF() { int i; DEV_INSTANCE *next = NULL; if(cif_nr_devs != 0) { cif_drv_unload(); for(i=0;inext; free(cif_devices); } // printf( "DevExitBoard RetWert = %5d \n", res); } } //************************************************************************* //* insert_CIF() * //* Insert specific controller parameters * //************************************************************************* void insert_CIF(controller *ctr,int n_contr,char *Basa,int mode) { char str[256]; if(mode==InsContr) { GetFieldItDbf(Basa,n_contr,"SPEED",str); ctr[n_contr].baud= atoi(str); if(ctr[n_contr].baud >= sizeof(par_bus)/sizeof(Spar_bus1)) ctr[n_contr].baud=sizeof(par_bus)/sizeof(Spar_bus1); GetFieldItDbf(Basa,n_contr,"PORT",str); ctr[n_contr].nomport=atoi(str); GetFieldItDbf(Basa,n_contr,"ADRES",str); ctr[n_contr].basaddr=atoi(str); } } //************************************************************************* //* GetDB_CIF() * //* * //************************************************************************* int GetDB_CIF(char n_port,char n_st,char n_task,int n_db,long offset, int len,char *buffer) { RCS_MESSAGE tMsg; int res, e_try = 4; if(len>240) return(-1); if(n_port>=cif_nr_devs || CIF_CTR[n_port] == NULL) return(-2); request_resource(CIF_CTR[n_port]->port_rsc,0*HZ); // захват поpта-pесурса // eprintf(GRAY_,"Dev = %xh; St = %xh; Task = %xh; DB = %d; DBoffs = %d; Len = %d",n_port,n_st,n_task,n_db,offset,len); do { e_try--; while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); tMsg.rx = 3; tMsg.tx = 16; tMsg.ln = 8; tMsg.nr = n_task; tMsg.a = 0; tMsg.f = 0; tMsg.b = MPI_Read_Write_DB; tMsg.e = 0; tMsg.d[0] = n_st; //PB адрес контроллера tMsg.d[1] = (unsigned char)(offset>>8); //Старший байт смещения tMsg.d[2] = (unsigned char)n_db; //Младший байт номера BD tMsg.d[3] = (unsigned char)(n_db>>8); //Старший байт номера BD tMsg.d[4] = (unsigned char)offset; //Младший байт смещения tMsg.d[5] = (unsigned char)len; //Длина сообщения tMsg.d[6] = TASK_TDT_UINT8; tMsg.d[7] = TASK_TFC_READ; res=DevPutMessage(n_port,&tMsg, 200L); if(res==DRV_DEV_PUT_TIMEOUT) { while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); release_resource(CIF_CTR[n_port]->port_rsc); return(-3); } if(res==DRV_NO_ERROR) res=DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 200L,n_task); } while( (tMsg.f == 0x02 || tMsg.f == 0x39) && e_try > 0 ); // if(res=SendReceiveMessage(n_port,(RCS_MESSAGE*)&tMsg)) // { eprintf(RED_,"Get Data err %d",res); return(-3); } release_resource(CIF_CTR[n_port]->port_rsc); if(res==DRV_DEV_GET_TIMEOUT) return(-4); memcpy(buffer,tMsg.d+8,len); return(tMsg.f); } //************************************************************************* //* PutDB_CIF() * //* * //************************************************************************* int PutDB_CIF(char n_port,char n_st,char n_task,int n_db,long offset, int len,char *buffer) { RCS_MESSAGE tMsg; int res, e_try = 4; if(len>240) return(-1); if(n_port>=cif_nr_devs || CIF_CTR[n_port] == NULL) return(-2); request_resource(CIF_CTR[n_port]->port_rsc,0*HZ); // захват поpта-pесурса do { e_try--; tMsg.rx = 3; tMsg.tx = 16; tMsg.ln = len+8; tMsg.nr = n_task; tMsg.a = 0; tMsg.f = 0; tMsg.b = MPI_Read_Write_DB; tMsg.e = 0; tMsg.d[0] = n_st; //PB адрес контроллера tMsg.d[1] = (unsigned char)(offset>>8); //Старший байт смещения tMsg.d[2] = (unsigned char)n_db; //Младший байт номера BD tMsg.d[3] = (unsigned char)(n_db>>8); //Старший байт номера BD tMsg.d[4] = (unsigned char)offset; //Младший байт смещения tMsg.d[5] = (unsigned char)len; //Длина сообщения tMsg.d[6] = TASK_TDT_UINT8; tMsg.d[7] = TASK_TFC_WRITE; memcpy(tMsg.d+8,buffer,len); res=DevPutMessage(n_port,&tMsg,200L); if(res==DRV_DEV_PUT_TIMEOUT) { while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); release_resource(CIF_CTR[n_port]->port_rsc); return(-3); } if(res==DRV_NO_ERROR) res=DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 200L,n_task); } while( (tMsg.f == 0x02 || tMsg.f == 0x39) && e_try > 0 ); release_resource(CIF_CTR[n_port]->port_rsc); // if(SendReceiveMessage(n_port,(RCS_MESSAGE*)&tMsg)) return(-3); if(res==DRV_DEV_GET_TIMEOUT) return(-4); return(tMsg.f); } //************************************************************************* //* MPI_disconnect_CIF * //* * //************************************************************************* int MPI_disconnect_CIF(char n_port,char n_task) { RCS_MESSAGE tMsg; int res; if(n_port>=cif_nr_devs || CIF_CTR[n_port] == NULL) return(-2); request_resource(CIF_CTR[n_port]->port_rsc,0*HZ); // захват поpта-pесурса tMsg.rx = 3; tMsg.tx = 16; tMsg.ln = 0; tMsg.nr = n_task; tMsg.a = 0; tMsg.f = 0; tMsg.b = MPI_Disconnect; tMsg.e = 0; res=DevPutMessage(n_port,&tMsg,200L); if(res==DRV_DEV_PUT_TIMEOUT) { while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); release_resource(CIF_CTR[n_port]->port_rsc); return(-3); } if(res==DRV_NO_ERROR) res=DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 200L,n_task); release_resource(CIF_CTR[n_port]->port_rsc); if(res==DRV_DEV_GET_TIMEOUT) return(-4); return(tMsg.f); } //************************************************************************* //* FindSt_CIF() * //* * //************************************************************************* int FindSt_CIF(char n_port,char n_st,char n_task) { int res; RCS_MESSAGE tMsg; RCS_TELEGRAMHEADER_10 *ptRcsTelegramheader10; DEV_INSTANCE *dev = NULL; if(n_port>=cif_nr_devs || CIF_CTR[n_port] == NULL) return(-2); request_resource(CIF_CTR[n_port]->port_rsc,0*HZ); // захват поpта-pесурса if((dev = (DEV_INSTANCE *)cif_dev_get_at(n_port))==NULL) { release_resource(CIF_CTR[n_port]->port_rsc); return(-1); } if(dev->usOpenCounter==0) { release_resource(CIF_CTR[n_port]->port_rsc); return(-1); } if((1*HZ+dev->last_jiffies)device_adr = 0; //char ptRcsTelegramheader10->data_area = 0; //char ptRcsTelegramheader10->data_adr = 0; //short ptRcsTelegramheader10->data_idx = 0; //char ptRcsTelegramheader10->data_cnt = DPM_MAX_NUM_DEVICES; //char ptRcsTelegramheader10->data_idx = 0; //char ptRcsTelegramheader10->data_type = TASK_TDT_STRING; //char ptRcsTelegramheader10->function = TASK_TFC_READ; //char res=DevPutMessage(n_port,&tMsg,200L); if(res==DRV_DEV_PUT_TIMEOUT) { while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); release_resource(CIF_CTR[n_port]->port_rsc); return(-3); } if(res==DRV_NO_ERROR) res=DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 200L,n_task); if(res==DRV_DEV_GET_TIMEOUT) { release_resource(CIF_CTR[n_port]->port_rsc); return(-4); } if(tMsg.f) { release_resource(CIF_CTR[n_port]->port_rsc); return(-5); } memcpy(dev->abLifeList,(void*)&tMsg.d[sizeof(RCS_TELEGRAMHEADER_10)],sizeof(dev->abLifeList)); dev->last_jiffies=jiffies(); } release_resource(CIF_CTR[n_port]->port_rsc); if(dev->abLifeList[n_st]==0x30) { // while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); // while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task|0x80)); return(1); } return(0); } //************************************************************************* //* GetStatContrCIF * //* Open CIF driver * //************************************************************************* int GetStatContrCIF(char n_port,char n_task) { RCS_MESSAGE tMsg; int res; if(n_port>=cif_nr_devs || CIF_CTR[n_port] == NULL) return(-2); request_resource(CIF_CTR[n_port]->port_rsc,0*HZ); // захват поpта-pесурса while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); tMsg.rx = 3; tMsg.tx = 16; tMsg.ln = 0; tMsg.nr = n_task; tMsg.a = 0; tMsg.f = 0; tMsg.b = MPI_Get_OP_Status; tMsg.e = 0; res=DevPutMessage(n_port,&tMsg,200L); if(res==DRV_DEV_PUT_TIMEOUT) { while(!DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 0L,n_task)); release_resource(CIF_CTR[n_port]->port_rsc); return(-3); } if(res==DRV_NO_ERROR) res=DevGetMessage(n_port,sizeof(RCS_MESSAGE),(MSG_STRUC *)&tMsg, 200L,n_task); release_resource(CIF_CTR[n_port]->port_rsc); if(res==DRV_DEV_GET_TIMEOUT) return(-4); return(*(short *)tMsg.d); } //************************************************************************* //* cif_open * //* Open CIF driver * //************************************************************************* //int cif_open(short CIF_nmb) //{ // if (CIF_nmb >= cif_nr_devs) return -ENODEV; // MOD_INC_USE_COUNT; // return 0; /* success */ //} //************************************************************************* //* cif_release * //* Close CIF driver * //************************************************************************* //int cif_release(struct inode *inode, struct file *filp) //{ MOD_DEC_USE_COUNT; return (0); } //void enable_CIF() //{ // int res = 0,i,j; // union REGS *pregs;