📄 istallion.c
字号:
#define ECP_EIMEMARL 1#define ECP_EICONFR 2#define ECP_EIMEMARH 3#define ECP_EIENABLE 0x1#define ECP_EIDISABLE 0x0#define ECP_EISTOP 0x4#define ECP_EIEDGE 0x00#define ECP_EILEVEL 0x80#define ECP_EIADDRMASKL 0x00ff0000#define ECP_EIADDRSHFTL 16#define ECP_EIADDRMASKH 0xff000000#define ECP_EIADDRSHFTH 24#define ECP_EIBRDENAB 0xc84#define ECP_EISAID 0x4/* * Important defines for the Micro-channel class of ECP board. * (It has a lot in common with the ISA boards.) */#define ECP_MCIREG 0#define ECP_MCCONFR 1#define ECP_MCSTOP 0x20#define ECP_MCENABLE 0x80#define ECP_MCDISABLE 0x00/* * Important defines for the PCI class of ECP board. * (It has a lot in common with the other ECP boards.) */#define ECP_PCIIREG 0#define ECP_PCICONFR 1#define ECP_PCISTOP 0x01/* * Hardware configuration info for ONboard and Brumby boards. These * defines apply to the directly accessible io ports of these boards. */#define ONB_IOSIZE 16#define ONB_MEMSIZE (64 * 1024)#define ONB_ATPAGESIZE (64 * 1024)#define ONB_MCPAGESIZE (64 * 1024)#define ONB_EIMEMSIZE (128 * 1024)#define ONB_EIPAGESIZE (64 * 1024)/* * Important defines for the ISA class of ONboard board. */#define ONB_ATIREG 0#define ONB_ATMEMAR 1#define ONB_ATCONFR 2#define ONB_ATSTOP 0x4#define ONB_ATENABLE 0x01#define ONB_ATDISABLE 0x00#define ONB_ATADDRMASK 0xff0000#define ONB_ATADDRSHFT 16#define ONB_MEMENABLO 0#define ONB_MEMENABHI 0x02/* * Important defines for the EISA class of ONboard board. */#define ONB_EIIREG 0#define ONB_EIMEMARL 1#define ONB_EICONFR 2#define ONB_EIMEMARH 3#define ONB_EIENABLE 0x1#define ONB_EIDISABLE 0x0#define ONB_EISTOP 0x4#define ONB_EIEDGE 0x00#define ONB_EILEVEL 0x80#define ONB_EIADDRMASKL 0x00ff0000#define ONB_EIADDRSHFTL 16#define ONB_EIADDRMASKH 0xff000000#define ONB_EIADDRSHFTH 24#define ONB_EIBRDENAB 0xc84#define ONB_EISAID 0x1/* * Important defines for the Brumby boards. They are pretty simple, * there is not much that is programmably configurable. */#define BBY_IOSIZE 16#define BBY_MEMSIZE (64 * 1024)#define BBY_PAGESIZE (16 * 1024)#define BBY_ATIREG 0#define BBY_ATCONFR 1#define BBY_ATSTOP 0x4/* * Important defines for the Stallion boards. They are pretty simple, * there is not much that is programmably configurable. */#define STAL_IOSIZE 16#define STAL_MEMSIZE (64 * 1024)#define STAL_PAGESIZE (64 * 1024)/* * Define the set of status register values for EasyConnection panels. * The signature will return with the status value for each panel. From * this we can determine what is attached to the board - before we have * actually down loaded any code to it. */#define ECH_PNLSTATUS 2#define ECH_PNL16PORT 0x20#define ECH_PNLIDMASK 0x07#define ECH_PNLXPID 0x40#define ECH_PNLINTRPEND 0x80/* * Define some macros to do things to the board. Even those these boards * are somewhat related there is often significantly different ways of * doing some operation on it (like enable, paging, reset, etc). So each * board class has a set of functions which do the commonly required * operations. The macros below basically just call these functions, * generally checking for a NULL function - which means that the board * needs nothing done to it to achieve this operation! */#define EBRDINIT(brdp) \ if (brdp->init != NULL) \ (* brdp->init)(brdp)#define EBRDENABLE(brdp) \ if (brdp->enable != NULL) \ (* brdp->enable)(brdp);#define EBRDDISABLE(brdp) \ if (brdp->disable != NULL) \ (* brdp->disable)(brdp);#define EBRDINTR(brdp) \ if (brdp->intr != NULL) \ (* brdp->intr)(brdp);#define EBRDRESET(brdp) \ if (brdp->reset != NULL) \ (* brdp->reset)(brdp);#define EBRDGETMEMPTR(brdp,offset) \ (* brdp->getmemptr)(brdp, offset, __LINE__)/* * Define the maximal baud rate, and the default baud base for ports. */#define STL_MAXBAUD 460800#define STL_BAUDBASE 115200#define STL_CLOSEDELAY (5 * HZ / 10)/*****************************************************************************//* * Define macros to extract a brd or port number from a minor number. */#define MINOR2BRD(min) (((min) & 0xc0) >> 6)#define MINOR2PORT(min) ((min) & 0x3f)/* * Define a baud rate table that converts termios baud rate selector * into the actual baud rate value. All baud rate calculations are based * on the actual baud rate required. */static unsigned int stli_baudrates[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600};/*****************************************************************************//* * Define some handy local macros... */#undef MIN#define MIN(a,b) (((a) <= (b)) ? (a) : (b))#undef TOLOWER#define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))/*****************************************************************************//* * Prototype all functions in this driver! */#ifdef MODULEint init_module(void);void cleanup_module(void);static void stli_argbrds(void);static int stli_parsebrd(stlconf_t *confp, char **argp);static unsigned long stli_atol(char *str);#endifint stli_init(void);static int stli_open(struct tty_struct *tty, struct file *filp);static void stli_close(struct tty_struct *tty, struct file *filp);static int stli_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);static void stli_putchar(struct tty_struct *tty, unsigned char ch);static void stli_flushchars(struct tty_struct *tty);static int stli_writeroom(struct tty_struct *tty);static int stli_charsinbuffer(struct tty_struct *tty);static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);static void stli_settermios(struct tty_struct *tty, struct termios *old);static void stli_throttle(struct tty_struct *tty);static void stli_unthrottle(struct tty_struct *tty);static void stli_stop(struct tty_struct *tty);static void stli_start(struct tty_struct *tty);static void stli_flushbuffer(struct tty_struct *tty);static void stli_breakctl(struct tty_struct *tty, int state);static void stli_waituntilsent(struct tty_struct *tty, int timeout);static void stli_sendxchar(struct tty_struct *tty, char ch);static void stli_hangup(struct tty_struct *tty);static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos);static int stli_brdinit(stlibrd_t *brdp);static int stli_startbrd(stlibrd_t *brdp);static ssize_t stli_memread(struct file *fp, char *buf, size_t count, loff_t *offp);static ssize_t stli_memwrite(struct file *fp, const char *buf, size_t count, loff_t *offp);static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);static void stli_poll(unsigned long arg);static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);static int stli_initopen(stlibrd_t *brdp, stliport_t *portp);static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp);static void stli_dohangup(void *arg);static void stli_delay(int len);static int stli_setport(stliport_t *portp);static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp);static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp);static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);static long stli_mktiocm(unsigned long sigvalue);static void stli_read(stlibrd_t *brdp, stliport_t *portp);static void stli_getserial(stliport_t *portp, struct serial_struct *sp);static int stli_setserial(stliport_t *portp, struct serial_struct *sp);static int stli_getbrdstats(combrd_t *bp);static int stli_getportstats(stliport_t *portp, comstats_t *cp);static int stli_portcmdstats(stliport_t *portp);static int stli_clrportstats(stliport_t *portp, comstats_t *cp);static int stli_getportstruct(unsigned long arg);static int stli_getbrdstruct(unsigned long arg);static void *stli_memalloc(int len);static stlibrd_t *stli_allocbrd(void);static void stli_ecpinit(stlibrd_t *brdp);static void stli_ecpenable(stlibrd_t *brdp);static void stli_ecpdisable(stlibrd_t *brdp);static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_ecpreset(stlibrd_t *brdp);static void stli_ecpintr(stlibrd_t *brdp);static void stli_ecpeiinit(stlibrd_t *brdp);static void stli_ecpeienable(stlibrd_t *brdp);static void stli_ecpeidisable(stlibrd_t *brdp);static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_ecpeireset(stlibrd_t *brdp);static void stli_ecpmcenable(stlibrd_t *brdp);static void stli_ecpmcdisable(stlibrd_t *brdp);static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_ecpmcreset(stlibrd_t *brdp);static void stli_ecppciinit(stlibrd_t *brdp);static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_ecppcireset(stlibrd_t *brdp);static void stli_onbinit(stlibrd_t *brdp);static void stli_onbenable(stlibrd_t *brdp);static void stli_onbdisable(stlibrd_t *brdp);static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_onbreset(stlibrd_t *brdp);static void stli_onbeinit(stlibrd_t *brdp);static void stli_onbeenable(stlibrd_t *brdp);static void stli_onbedisable(stlibrd_t *brdp);static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_onbereset(stlibrd_t *brdp);static void stli_bbyinit(stlibrd_t *brdp);static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_bbyreset(stlibrd_t *brdp);static void stli_stalinit(stlibrd_t *brdp);static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);static void stli_stalreset(stlibrd_t *brdp);static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);static inline int stli_initbrds(void);static inline int stli_initecp(stlibrd_t *brdp);static inline int stli_initonb(stlibrd_t *brdp);static inline int stli_findeisabrds(void);static inline int stli_eisamemprobe(stlibrd_t *brdp);static inline int stli_initports(stlibrd_t *brdp);static inline int stli_getbrdnr(void);#ifdef CONFIG_PCIstatic inline int stli_findpcibrds(void);static inline int stli_initpcibrd(int brdtype, struct pci_dev *devp);#endif/*****************************************************************************//* * Define the driver info for a user level shared memory device. This * device will work sort of like the /dev/kmem device - except that it * will give access to the shared memory on the Stallion intelligent * board. This is also a very useful debugging tool. */static struct file_operations stli_fsiomem = { owner: THIS_MODULE, read: stli_memread, write: stli_memwrite, ioctl: stli_memioctl,};/*****************************************************************************//* * Define a timer_list entry for our poll routine. The slave board * is polled every so often to see if anything needs doing. This is * much cheaper on host cpu than using interrupts. It turns out to * not increase character latency by much either... */static struct timer_list stli_timerlist = { function: stli_poll};static int stli_timeron;/* * Define the calculation for the timeout routine. */#define STLI_TIMEOUT (jiffies + 1)/*****************************************************************************/#ifdef MODULE/* * Loadable module initialization stuff. */int init_module(){ unsigned long flags;#if DEBUG printk("init_module()\n");#endif save_flags(flags); cli(); stli_init(); restore_flags(flags); return(0);}/*****************************************************************************/void cleanup_module(){ stlibrd_t *brdp; stliport_t *portp; unsigned long flags; int i, j;#if DEBUG printk("cleanup_module()\n");#endif printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, stli_drvversion); save_flags(flags); cli();/* * Free up all allocated resources used by the ports. This includes * memory and interrupts. */ if (stli_timeron) { stli_timeron = 0; del_timer(&stli_timerlist); } i = tty_unregister_driver(&stli_serial); j = tty_unregister_driver(&stli_callout); if (i || j) { printk("STALLION: failed to un-register tty driver, " "errno=%d,%d\n", -i, -j); restore_flags(flags); return; } devfs_unregister (devfs_handle); if ((i = devfs_unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) printk("STALLION: failed to un-register serial memory device, " "errno=%d\n", -i); if (stli_tmpwritebuf != (char *) NULL) kfree(stli_tmpwritebuf); if (stli_txcookbuf != (char *) NULL) kfree(stli_txcookbuf); for (i = 0; (i < stli_nrbrds); i++) { if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL) continue; for (j = 0; (j < STL_MAXPORTS); j++) { portp = brdp->ports[j]; if (portp != (stliport_t *) NULL) { if (portp->tty != (struct tty_struct *) NULL) tty_hangup(portp->tty); kfree(portp); } } iounmap(brdp->membase); if (brdp->iosize > 0) release_region(brdp->iobase, brdp->iosize); kfree(brdp); stli_brds[i] = (stlibrd_t *) NULL; } restore_flags(flags);}/*****************************************************************************//* * Check for any arguments passed in on the module load command line. */static void stli_argbrds(){ stlconf_t conf; stlibrd_t *brdp; int nrargs, i;#if DEBUG printk("stli_argbrds()\n");#endif nrargs = sizeof(stli_brdsp) / sizeof(char **); for (i = stli_nrbrds; (i < nrargs); i++) { memset(&conf, 0, sizeof(conf)); if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) continue; if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) continue; stli_nrbrds = i + 1; brdp->brdnr = i; brdp->brdtype = conf.brdtype; brdp->iobase = conf.ioaddr1; brdp->memaddr = conf.memaddr; stli_brdinit(brdp); }}/*****************************************************************************//* * Convert an ascii string number into an unsigned long. */static unsigned long stli_atol(char *str){ unsigned long val; int base, c; char *sp; val = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -