📄 moxa.c
字号:
*/#define Rx_over 0x01#define Xoff_state 0x02#define Tx_flowOff 0x04#define Tx_enable 0x08#define CTS_state 0x10#define DSR_state 0x20#define DCD_state 0x80/* * FlowControl */#define CTS_FlowCtl 1#define RTS_FlowCtl 2#define Tx_FlowCtl 4#define Rx_FlowCtl 8#define IXM_IXANY 0x10#define LowWater 128#define DTR_ON 1#define RTS_ON 2#define CTS_ON 1#define DSR_ON 2#define DCD_ON 8/* mode definition */#define MX_CS8 0x03#define MX_CS7 0x02#define MX_CS6 0x01#define MX_CS5 0x00#define MX_STOP1 0x00#define MX_STOP15 0x04#define MX_STOP2 0x08#define MX_PARNONE 0x00#define MX_PAREVEN 0x40#define MX_PARODD 0xC0/* * Query */#define QueryPort MAX_PORTSstruct mon_str { int tick; int rxcnt[MAX_PORTS]; int txcnt[MAX_PORTS];};typedef struct mon_str mon_st;#define DCD_changed 0x01#define DCD_oldstate 0x80static unsigned char moxaBuff[10240];static unsigned long moxaIntNdx[MAX_BOARDS];static unsigned long moxaIntPend[MAX_BOARDS];static unsigned long moxaIntTable[MAX_BOARDS];static char moxaChkPort[MAX_PORTS];static char moxaLineCtrl[MAX_PORTS];static unsigned long moxaTableAddr[MAX_PORTS];static long moxaCurBaud[MAX_PORTS];static char moxaDCDState[MAX_PORTS];static char moxaLowChkFlag[MAX_PORTS];static int moxaLowWaterChk;static int moxaCard;static mon_st moxaLog;static int moxaFuncTout;static ushort moxaBreakCnt[MAX_PORTS];static void moxadelay(int);static void moxafunc(unsigned long, int, ushort);static void wait_finish(unsigned long);static void low_water_check(unsigned long);static int moxaloadbios(int, unsigned char __user *, int);static int moxafindcard(int);static int moxaload320b(int, unsigned char __user *, int);static int moxaloadcode(int, unsigned char __user *, int);static int moxaloadc218(int, unsigned long, int);static int moxaloadc320(int, unsigned long, int, int *);/***************************************************************************** * Driver level functions: * * 1. MoxaDriverInit(void); * * 2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); * * 3. MoxaDriverPoll(void); * *****************************************************************************/void MoxaDriverInit(void){ int i; moxaFuncTout = HZ / 2; /* 500 mini-seconds */ moxaCard = 0; moxaLog.tick = 0; moxaLowWaterChk = 0; for (i = 0; i < MAX_PORTS; i++) { moxaChkPort[i] = 0; moxaLowChkFlag[i] = 0; moxaLineCtrl[i] = 0; moxaLog.rxcnt[i] = 0; moxaLog.txcnt[i] = 0; }}#define MOXA 0x400#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */#define MOXA_INIT_DRIVER (MOXA + 6) /* moxaCard=0 */#define MOXA_LOAD_BIOS (MOXA + 9) /* download BIOS */#define MOXA_FIND_BOARD (MOXA + 10) /* Check if MOXA card exist? */#define MOXA_LOAD_C320B (MOXA + 11) /* download 320B firmware */#define MOXA_LOAD_CODE (MOXA + 12) /* download firmware */#define MOXA_GETDATACOUNT (MOXA + 23)#define MOXA_GET_IOQUEUE (MOXA + 27)#define MOXA_FLUSH_QUEUE (MOXA + 28)#define MOXA_GET_CONF (MOXA + 35) /* configuration */#define MOXA_GET_MAJOR (MOXA + 63)#define MOXA_GET_CUMAJOR (MOXA + 64)#define MOXA_GETMSTATUS (MOXA + 65)struct moxaq_str { int inq; int outq;};struct dl_str { char __user *buf; int len; int cardno;};static struct moxaq_str temp_queue[MAX_PORTS];static struct dl_str dltmp;void MoxaPortFlushData(int port, int mode){ unsigned long ofsAddr; if ((mode < 0) || (mode > 2)) return; ofsAddr = moxaTableAddr[port]; moxafunc(ofsAddr, FC_FlushQueue, mode); if (mode != 1) { moxaLowChkFlag[port] = 0; low_water_check(ofsAddr); }}int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port){ int i; int status; int MoxaPortTxQueue(int), MoxaPortRxQueue(int); void __user *argp = (void __user *)arg; if (port == QueryPort) { if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) && (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) && (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) && (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) && (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS)) return (-EINVAL); } switch (cmd) { case MOXA_GET_CONF: if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf))) return -EFAULT; return (0); case MOXA_INIT_DRIVER: if ((int) arg == 0x404) MoxaDriverInit(); return (0); case MOXA_GETDATACOUNT: moxaLog.tick = jiffies; if(copy_to_user(argp, &moxaLog, sizeof(mon_st))) return -EFAULT; return (0); case MOXA_FLUSH_QUEUE: MoxaPortFlushData(port, arg); return (0); case MOXA_GET_IOQUEUE: for (i = 0; i < MAX_PORTS; i++) { if (moxaChkPort[i]) { temp_queue[i].inq = MoxaPortRxQueue(i); temp_queue[i].outq = MoxaPortTxQueue(i); } } if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS)) return -EFAULT; return (0); case MOXA_GET_OQUEUE: i = MoxaPortTxQueue(port); return put_user(i, (unsigned long __user *)argp); case MOXA_GET_IQUEUE: i = MoxaPortRxQueue(port); return put_user(i, (unsigned long __user *)argp); case MOXA_GET_MAJOR: if(copy_to_user(argp, &ttymajor, sizeof(int))) return -EFAULT; return 0; case MOXA_GET_CUMAJOR: i = 0; if(copy_to_user(argp, &i, sizeof(int))) return -EFAULT; return 0; case MOXA_GETMSTATUS: for (i = 0; i < MAX_PORTS; i++) { GMStatus[i].ri = 0; GMStatus[i].dcd = 0; GMStatus[i].dsr = 0; GMStatus[i].cts = 0; if (!moxaChkPort[i]) { continue; } else { status = MoxaPortLineStatus(moxaChannels[i].port); if (status & 1) GMStatus[i].cts = 1; if (status & 2) GMStatus[i].dsr = 1; if (status & 4) GMStatus[i].dcd = 1; } if (!moxaChannels[i].tty || !moxaChannels[i].tty->termios) GMStatus[i].cflag = moxaChannels[i].cflag; else GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag; } if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS)) return -EFAULT; return 0; default: return (-ENOIOCTLCMD); case MOXA_LOAD_BIOS: case MOXA_FIND_BOARD: case MOXA_LOAD_C320B: case MOXA_LOAD_CODE: break; } if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) return -EFAULT; if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) return -EINVAL; switch(cmd) { case MOXA_LOAD_BIOS: i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len); return (i); case MOXA_FIND_BOARD: return moxafindcard(dltmp.cardno); case MOXA_LOAD_C320B: moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len); default: /* to keep gcc happy */ return (0); case MOXA_LOAD_CODE: i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len); if (i == -1) return (-EFAULT); return (i); }}int MoxaDriverPoll(void){ register ushort temp; register int card; unsigned long ip, ofsAddr; int port, p, ports; if (moxaCard == 0) return (-1); for (card = 0; card < MAX_BOARDS; card++) { if ((ports = moxa_boards[card].numPorts) == 0) continue; if (readb(moxaIntPend[card]) == 0xff) { ip = moxaIntTable[card] + readb(moxaIntNdx[card]); p = card * MAX_PORTS_PER_BOARD; ports <<= 1; for (port = 0; port < ports; port += 2, p++) { if ((temp = readw(ip + port)) != 0) { writew(0, ip + port); ofsAddr = moxaTableAddr[p]; if (temp & IntrTx) writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat); if (temp & IntrBreak) { moxaBreakCnt[p]++; } if (temp & IntrLine) { if (readb(ofsAddr + FlagStat) & DCD_state) { if ((moxaDCDState[p] & DCD_oldstate) == 0) moxaDCDState[p] = (DCD_oldstate | DCD_changed); } else { if (moxaDCDState[p] & DCD_oldstate) moxaDCDState[p] = DCD_changed; } } } } writeb(0, moxaIntPend[card]); } if (moxaLowWaterChk) { p = card * MAX_PORTS_PER_BOARD; for (port = 0; port < ports; port++, p++) { if (moxaLowChkFlag[p]) { moxaLowChkFlag[p] = 0; ofsAddr = moxaTableAddr[p]; low_water_check(ofsAddr); } } } } moxaLowWaterChk = 0; return (0);}/***************************************************************************** * Card level function: * * 1. MoxaPortsOfCard(int cardno); * *****************************************************************************/int MoxaPortsOfCard(int cardno){ if (moxa_boards[cardno].boardType == 0) return (0); return (moxa_boards[cardno].numPorts);}/***************************************************************************** * Port level functions: * * 1. MoxaPortIsValid(int port); * * 2. MoxaPortEnable(int port); * * 3. MoxaPortDisable(int port); * * 4. MoxaPortGetMaxBaud(int port); * * 5. MoxaPortGetCurBaud(int port); * * 6. MoxaPortSetBaud(int port, long baud); * * 7. MoxaPortSetMode(int port, int databit, int stopbit, int parity); * * 8. MoxaPortSetTermio(int port, unsigned char *termio); * * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); * * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); * * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); * * 12. MoxaPortLineStatus(int port); * * 13. MoxaPortDCDChange(int port); * * 14. MoxaPortDCDON(int port); * * 15. MoxaPortFlushData(int port, int mode); * * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * * 17. MoxaPortReadData(int port, unsigned char * buffer, int length); * * 18. MoxaPortTxBufSize(int port); * * 19. MoxaPortRxBufSize(int port); * * 20. MoxaPortTxQueue(int port); * * 21. MoxaPortTxFree(int port); * * 22. MoxaPortRxQueue(int port); * * 23. MoxaPortRxFree(int port); * * 24. MoxaPortTxDisable(int port); * * 25. MoxaPortTxEnable(int port); * * 26. MoxaPortGetBrkCnt(int port); * * 27. MoxaPortResetBrkCnt(int port); * * 28. MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); * * 29. MoxaPortIsTxHold(int port); * * 30. MoxaPortSendBreak(int port, int ticks); * *****************************************************************************//* * Moxa Port Number Description: * * MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And, * the port number using in MOXA driver functions will be 0 to 31 for * first MOXA board, 32 to 63 for second, 64 to 95 for third and 96 * to 127 for fourth. For example, if you setup three MOXA boards, * first board is C218, second board is C320-16 and third board is * C320-32. The port number of first board (C218 - 8 ports) is from * 0 to 7. The port number of second board (C320 - 16 ports) is form * 32 to 47. The port number of third board (C320 - 32 ports) is from * 64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to * 127 will be invalid. * * * Moxa Functions Description: * * Function 1: Driver initialization routine, this routine must be * called when initialized driver. * Syntax: * void MoxaDriverInit(); * * * Function 2: Moxa driver private IOCTL command processing. * Syntax: * int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); * * unsigned int cmd : IOCTL command * unsigned long arg : IOCTL argument * int port : port number (0 - 127) * * return: 0 (OK) * -EINVAL * -ENOIOCTLCMD * * * Function 3: Moxa driver polling process routine. * Syntax: * int MoxaDriverPoll(void); * * return: 0 ; polling O.K. * -1 : no any Moxa card. * * * Function 4: Get the ports of this card. * Syntax: * int MoxaPortsOfCard(int cardno); * * int cardno : card number (0 - 3) * * return: 0 : this card is invalid * 8/16/24/32 * * * Function 5: Check this port is valid or invalid * Syntax: * int MoxaPortIsValid(int port); * int port : port number (0 - 127, ref port description) * * return: 0 : this port is invalid * 1 : this port is valid * * * Function 6: Enable this port to start Tx/Rx data. * Syntax: * void MoxaPortEnable(int port); * int port : port number (0 - 127) * * * Function 7: Disable this port * Syntax: * void MoxaPortDisable(int port); * int port : port number (0 - 127) * * * Function 8: Get the maximun available baud rate of this port. * Syntax: * long MoxaPortGetMaxBaud(int port); * int port : port number (0 - 127) * * return: 0 : this port is invalid * 38400/57600/115200 bps * * * Function 9: Get the current baud rate of this port. * Syntax: * long MoxaPortGetCurBaud(int port); * int port : port number (0 - 127) * * return: 0 : this port is invalid * 50 - 115200 bps * * * Function 10: Setting baud rate of this port. * Syntax: * long MoxaPortSetBaud(int port, long baud); * int port : port number (0 - 127) * long baud : baud rate (50 - 115200) * * return: 0 : this port is invalid or baud < 50 * 50 - 115200 : the real baud rate set to the port, if * the argument baud is large than maximun * available baud rate, the real setting * baud rate will be the maximun baud rate. * * * Function 11: Setting the data-bits/stop-bits/parity of this port * Syntax: * int MoxaPortSetMode(int port, int databits, int stopbits, int parity); * int port : port number (0 - 127) * int databits : data bits (8/7/6/5) * int stopbits : stop bits (2/1/0, 0 show 1.5 stop bits) int parity : parity (0:None,1:Odd,2:Even,3:Mark,4:Space) * * return: -1 : invalid parameter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -