?? du.c
字號:
/* * DU-11 Synchronous interface driver */#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/buf.h"/* device registers */struct dureg { int rxcsr, rxdbuf;#define parcsr rxdbuf int txcsr, txdbuf;};struct du { struct dureg *du_addr; int du_state; struct proc *du_proc; struct buf *du_buf; caddr_t du_bufb; caddr_t du_bufp; int du_nxmit; int du_timer;} du[] = { { (struct dureg *) 0160110 },};#define NDU (sizeof(du)/sizeof(du[0]))#define DONE 0200#define IE 0100#define SIE 040#define CTS 020000#define CARRIER 010000#define RCVACT 04000#define DSR 01000#define STRIP 0400#define SCH 020#define RTS 04#define DTR 02#define MR 0400#define SEND 020#define HALF 010#define READ 0#define WRITE 1#define PWRIT 2#define DUPRI (PZERO+1)duopen(dev)register dev;{ int dutimeout(); register struct du *dp; register struct dureg *lp; dev = minor(dev); if (dev >= NDU || ((dp = &du[dev])->du_proc!=NULL && dp->du_proc!=u.u_procp)) { u.u_error = ENXIO; return; } dp->du_proc = u.u_procp; lp = dp->du_addr; if (dp->du_buf==NULL) { dp->du_buf = geteblk(); dp->du_bufb = dp->du_buf->b_un.b_addr; dp->du_state = WRITE; lp->txcsr = MR; lp->parcsr = 035026; /* Sync Int, 7 bits, even parity, sync=026 */ timeout(dutimeout, (caddr_t)dp, HZ); duturn(dp); }}duclose(dev){ register struct du *dp; register struct dureg *lp; dp = &du[minor(dev)]; lp = dp->du_addr; lp->rxcsr = 0; lp->txcsr = 0; dp->du_timer = 0; dp->du_proc = 0; if (dp->du_buf != NULL) { brelse(dp->du_buf); dp->du_buf = NULL; }}duread(dev){ register char *bp; register struct du *dp; dp = &du[minor(dev)]; bp = dp->du_bufb; for(;;) { if(duwait(dev)) return; if (dp->du_bufp > bp) break; spl6(); if (dp->du_timer <= 1) { spl0(); return; } sleep((caddr_t)dp, DUPRI); spl0(); } u.u_offset = 0; iomove(dp->du_bufb, (int)min(u.u_count, (unsigned)(dp->du_bufp-bp)), B_READ);}duwrite(dev){ register struct du *dp; register struct dureg *lp; dev = minor(dev); dp = &du[dev]; if (u.u_count==0 || duwait(dev)) return; dp->du_bufp = dp->du_bufb; dp->du_state = PWRIT; dp->du_addr->rxcsr &= ~SCH; dp->du_addr->rxcsr = SIE|RTS|DTR; if (u.u_count > BSIZE) u.u_count = BSIZE; dp->du_nxmit = u.u_count; u.u_offset = 0; iomove(dp->du_bufb, (int)u.u_count, B_WRITE); lp = dp->du_addr; dp->du_timer = 10; spl6(); while((lp->rxcsr&CTS)==0) sleep((caddr_t)dp, DUPRI); if (dp->du_state != WRITE) { dp->du_state = WRITE; lp->txcsr = IE|SIE|SEND|HALF; dustart(dev); } spl0();}duwait(dev){ register struct du *dp; register struct dureg *lp; dp = &du[minor(dev)]; lp = dp->du_addr; for(;;) { if ((lp->rxcsr&DSR)==0 || dp->du_buf==0) { u.u_error = EIO; return(1); } spl6(); if (dp->du_state==READ && ((lp->rxcsr&RCVACT)==0)) { spl0(); return(0); } sleep((caddr_t)dp, DUPRI); spl0(); }}dustart(dev){ register struct du *dp; register struct dureg *lp; dp = &du[minor(dev)]; lp = dp->du_addr; dp->du_timer = 10; if (dp->du_nxmit > 0) { dp->du_nxmit--; lp->txdbuf = *dp->du_bufp++; } else { duturn(dp); }}durint(dev){ register struct du *dp; register c, s; int dustat; dp = &du[minor(dev)]; dustat = dp->du_addr->rxcsr; if(dustat<0) { if((dustat&CARRIER)==0 && dp->du_state==READ) duturn(dp); else wakeup((caddr_t)dp); } else if(dustat&DONE) { dp->du_addr->rxcsr = IE|SIE|SCH|DTR; c = s = dp->du_addr->rxdbuf; c &= 0177; if(s<0) c |= 0200; if (dp->du_bufp < dp->du_bufb+BSIZE) *dp->du_bufp++ = c; }}duxint(dev){ register struct du *dp; register struct dureg *lp; register int dustat; dp = &du[minor(dev)]; lp = dp->du_addr; dustat = lp->txcsr; if(dustat<0) duturn(dp); else if(dustat&DONE) dustart(dev);}duturn(dp)register struct du *dp;{ register struct dureg *lp; lp = dp->du_addr; if (dp->du_state!=READ) { dp->du_state = READ; dp->du_timer = 10; dp->du_bufp = dp->du_bufb; } lp->txcsr = HALF; lp->rxcsr &= ~SCH; lp->rxcsr = STRIP|IE|SIE|SCH|DTR; wakeup((caddr_t)dp);}dutimeout(dp)register struct du *dp;{ if (dp->du_timer == 0) return; if (--dp->du_timer == 0) { duturn(dp); dp->du_timer = 1; } timeout(dutimeout, (caddr_t)dp, HZ);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -