xref: /original-bsd/sys/vax/vax/crl.c (revision 7b081c7c)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)crl.c	7.3 (Berkeley) 02/17/90
7  */
8 /*
9  * TO DO (tef  7/18/85):
10  *	1) change printf's to log() instead???
11  */
12 
13 #if VAX8600
14 #include "param.h"
15 #include "systm.h"
16 #include "conf.h"
17 #include "user.h"
18 #include "buf.h"
19 
20 #include "cons.h"
21 #include "cpu.h"
22 #include "crl.h"
23 #include "mtpr.h"
24 
25 struct {
26 	short	crl_state;		/* open and busy flags */
27 	short	crl_active;		/* driver state flag */
28 	struct	buf *crl_buf;		/* buffer we're using */
29 	ushort *crl_xaddr;		/* transfer address */
30 	short	crl_errcnt;
31 } crltab;
32 
33 struct {
34 	int	crl_cs;		/* saved controller status */
35 	int	crl_ds;		/* saved drive status */
36 } crlstat;
37 
38 /*ARGSUSED*/
39 crlopen(dev, flag)
40 	dev_t dev;
41 	int flag;
42 {
43 	struct buf *geteblk();
44 
45 	if (cpu != VAX_8600)
46 		return (ENXIO);
47 	if (crltab.crl_state != CRL_IDLE)
48 		return (EALREADY);
49 	crltab.crl_state = CRL_OPEN;
50 	crltab.crl_buf = geteblk(512);
51 	return (0);
52 }
53 
54 /*ARGSUSED*/
55 crlclose(dev, flag)
56 	dev_t dev;
57 	int flag;
58 {
59 
60 	brelse(crltab.crl_buf);
61 	crltab.crl_state = CRL_IDLE;
62 }
63 
64 /*ARGSUSED*/
65 crlrw(dev, uio, flag)
66 	dev_t dev;
67 	struct uio *uio;
68 	int flag;
69 {
70 	register struct buf *bp;
71 	register int i;
72 	register int s;
73 	int error;
74 
75 	if (uio->uio_resid == 0)
76 		return (0);
77 	s = spl4();
78 	while (crltab.crl_state & CRL_BUSY)
79 		sleep((caddr_t)&crltab, PRIBIO);
80 	crltab.crl_state |= CRL_BUSY;
81 	splx(s);
82 
83 	bp = crltab.crl_buf;
84 	error = 0;
85 	while ((i = imin(CRLBYSEC, uio->uio_resid)) > 0) {
86 		bp->b_blkno = uio->uio_offset>>9;
87 		if (bp->b_blkno >= MAXSEC || (uio->uio_offset & 0x1FF) != 0) {
88 			error = EIO;
89 			break;
90 		}
91 		if (uio->uio_rw == UIO_WRITE) {
92 			error = uiomove(bp->b_un.b_addr, i, uio);
93 			if (error)
94 				break;
95 		}
96 		bp->b_flags = uio->uio_rw == UIO_WRITE ? B_WRITE : B_READ;
97 		s = spl4();
98 		crlstart();
99 		while ((bp->b_flags & B_DONE) == 0)
100 			sleep((caddr_t)bp, PRIBIO);
101 		splx(s);
102 		if (bp->b_flags & B_ERROR) {
103 			error = EIO;
104 			break;
105 		}
106 		if (uio->uio_rw == UIO_READ) {
107 			error = uiomove(bp->b_un.b_addr, i, uio);
108 			if (error)
109 				break;
110 		}
111 	}
112 	crltab.crl_state &= ~CRL_BUSY;
113 	wakeup((caddr_t)&crltab);
114 	return (error);
115 }
116 
117 crlstart()
118 {
119 	register struct buf *bp;
120 
121 	bp = crltab.crl_buf;
122 	crltab.crl_errcnt = 0;
123 	crltab.crl_xaddr = (ushort *) bp->b_un.b_addr;
124 	bp->b_resid = 0;
125 
126 	if ((mfpr(STXCS) & STXCS_RDY) == 0)
127 		/* not ready to receive order */
128 		return;
129 	if ((bp->b_flags&(B_READ|B_WRITE)) == B_READ) {
130 		crltab.crl_active = CRL_F_READ;
131 		mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ);
132 	} else {
133 		crltab.crl_active = CRL_F_WRITE;
134 		mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE);
135 	}
136 #ifdef lint
137 	crlintr();
138 #endif
139 }
140 
141 crlintr()
142 {
143 	register struct buf *bp;
144 	int i;
145 
146 	bp = crltab.crl_buf;
147 	i = mfpr(STXCS);
148 	switch ((i>>24) & 0xFF) {
149 
150 	case CRL_S_XCMPLT:
151 		switch (crltab.crl_active) {
152 
153 		case CRL_F_RETSTS:
154 			crlstat.crl_ds = mfpr(STXDB);
155 			printf("crlcs=0x%b, crlds=0x%b\n", crlstat.crl_cs,
156 				CRLCS_BITS, crlstat.crl_ds, CRLDS_BITS);
157 			break;
158 
159 		case CRL_F_READ:
160 		case CRL_F_WRITE:
161 			bp->b_flags |= B_DONE;
162 		}
163 		crltab.crl_active = 0;
164 		wakeup((caddr_t)bp);
165 		break;
166 
167 	case CRL_S_XCONT:
168 		switch (crltab.crl_active) {
169 
170 		case CRL_F_WRITE:
171 			mtpr(STXDB, *crltab.crl_xaddr++);
172 			mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE);
173 			break;
174 
175 		case CRL_F_READ:
176 			*crltab.crl_xaddr++ = mfpr(STXDB);
177 			mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ);
178 		}
179 		break;
180 
181 	case CRL_S_ABORT:
182 		crltab.crl_active = CRL_F_RETSTS;
183 		mtpr(STXCS, STXCS_IE | CRL_F_RETSTS);
184 		bp->b_flags |= B_DONE|B_ERROR;
185 		break;
186 
187 	case CRL_S_RETSTS:
188 		crlstat.crl_cs = mfpr(STXDB);
189 		mtpr(STXCS, STXCS_IE | CRL_S_RETSTS);
190 		break;
191 
192 	case CRL_S_HNDSHK:
193 		printf("crl: hndshk error\n");	/* dump out some status too? */
194 		crltab.crl_active = 0;
195 		bp->b_flags |= B_DONE|B_ERROR;
196 		wakeup((caddr_t)bp);
197 		break;
198 
199 	case CRL_S_HWERR:
200 		printf("crl: hard error sn%d\n", bp->b_blkno);
201 		crltab.crl_active = CRL_F_ABORT;
202 		mtpr(STXCS, STXCS_IE | CRL_F_ABORT);
203 		break;
204 	}
205 }
206 #endif
207