xref: /original-bsd/sys/news3400/iop/iop.c (revision 3705696b)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: iop.c,v 4.300 91/06/09 06:42:37 root Rel41 $ SONY
11  *
12  *	@(#)iop.c	8.1 (Berkeley) 06/11/93
13  */
14 
15 /*
16  *	iop.c / hb.c	ver 0.0
17  */
18 
19 #include <machine/machConst.h>
20 
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <sys/map.h>
24 #include <sys/buf.h>
25 #include <sys/proc.h>
26 #include <sys/user.h>
27 #include <sys/conf.h>
28 #include <sys/dkstat.h>
29 #include <sys/kernel.h>
30 #include <sys/malloc.h>
31 
32 #include <machine/pte.h>
33 #include <machine/cpu.h>
34 
35 #include <news3400/iodev/scsireg.h>
36 
37 #ifdef CPU_DOUBLE
38 #include "../iop/iopvar.h"
39 #endif
40 
41 #ifdef CPU_SINGLE
42 #include <news3400/hbdev/hbvar.h>
43 #include <news3400/hbdev/scsic.h>
44 struct scsi_stat scsi_stat;
45 #endif
46 
47 /*
48  * dual processor ===> single processor
49  */
50 #ifdef CPU_SINGLE
51 # define	iopreset	hbreset
52 # define	iopbuf		hbbuf
53 # define	iopalloc	hballoc
54 # define	iopsetup	hbsetup
55 # define	iop_ctlr	hb_ctlr
56 # define	iop_device	hb_device
57 # define	iopgo		hbgo
58 
59 # define	im_driver	hm_driver
60 # define	im_ctlr		hm_ctlr
61 # define	im_alive	hm_alive
62 # define	im_addr		hm_addr
63 # define	im_intr		hm_intr
64 # define	im_scnum	hm_scnum
65 # define	im_hd		hm_hd
66 # define	im_hbinfo	hm_hbinfo
67 # define	im_tab		hm_tab
68 
69 # define	ii_driver	hi_driver
70 # define	ii_unit		hi_unit
71 # define	ii_ctlr		hi_ctlr
72 # define	ii_slave	hi_slave
73 # define	ii_addr		hi_addr
74 # define	ii_intr		hi_intr
75 # define	ii_dk		hi_dk
76 # define	ii_flags	hi_flags
77 # define	ii_alive	hi_alive
78 # define	ii_type		hi_type
79 # define	ii_forw		hi_forw
80 # define	ii_mi		hi_mi
81 # define	ii_hd		hi_hd
82 
83 # define	id_dgo		hd_dgo
84 #endif /* CPU_SINGLE */
85 
86 iopgo(ii, map)
87 	register struct iop_device *ii;
88 	struct sc_map *map;
89 {
90 	register struct iop_ctlr *im = ii->ii_mi;
91 	register int unit;
92 	int s;
93 
94 	s = spl6();
95 	if (map)
96 		(void)iopsetup(im->im_tab.b_actf->b_actf, map, NSCMAP);
97 	splx(s);
98 	if (ii->ii_dk >= 0) {
99 		unit = ii->ii_dk;
100 		dk_busy |= 1<<unit;
101 		dk_xfer[unit]++;
102 		dk_wds[unit] += im->im_tab.b_actf->b_actf->b_bcount>>6;
103 	}
104 	if (im->im_driver->id_dgo)
105 		(*im->im_driver->id_dgo)(im);
106 }
107 
108 iopsetup(bp, map, nmap)
109 	register struct buf *bp;
110 	struct sc_map *map;
111 	int nmap;
112 {
113 	register struct pte *pte;
114 	register unsigned *io;
115 	int o, npf;
116 
117 	o = (int)bp->b_un.b_addr & PGOFSET;
118 	map->mp_offset = o;
119 	npf = btoc(bp->b_bcount + o);
120 	if (npf > nmap)
121 		panic("sc_map setup: bcount too large");
122 	map->mp_pages = npf;
123 	io = map->mp_addr;
124 #ifdef mips
125 	if (MACH_IS_UNMAPPED(bp->b_un.b_addr)) {
126 		int	i;
127 
128 		for (i = 0; npf-- > 0; i++)
129 			*io++ = ((MACH_UNMAPPED_TO_PHYS(bp->b_un.b_addr))
130 				 >> PGSHIFT) + i;
131 		return (1);
132 	}
133 	else if ((bp->b_un.b_addr >= (caddr_t)VM_MIN_KERNEL_ADDRESS) &&
134 		 (bp->b_un.b_addr < (caddr_t)VM_MAX_KERNEL_ADDRESS)) {
135 		pte = (struct pte*)kvtopte(bp->b_un.b_addr);
136 		while (--npf >= 0) {
137 			if (pte->pg_pfnum == 0)
138 				panic("sc_map setup: zero pfnum");
139 			*io++ = pte++->pg_pfnum;
140 		}
141 		return (1);
142 	}
143 	else {
144 		panic("iopsetup: user address is not allowed");
145 	}
146 #else /* mips */
147 	ERROR!  This code does not work. /* KU:XXX */
148 	pte = buftopte(bp);
149 	while (--npf >= 0) {
150 		if (pte->pg_pfnum == 0)
151 			panic("sc_map setup: zero pfnum");
152 		*io++ = pte++->pg_pfnum;
153 	}
154 	return (1);
155 #endif /* mips */
156 }
157 
158 iopalloc(addr, bcnt, map, nmap)
159 	caddr_t addr;
160 	int bcnt, nmap;
161 	struct sc_map *map;
162 {
163 	struct buf iopbuf;
164 
165 	iopbuf.b_un.b_addr = addr;
166 	iopbuf.b_flags = B_BUSY;
167 	iopbuf.b_bcount = bcnt;
168 	/* that's all the fields iopsetup() needs */
169 	return (iopsetup(&iopbuf, map, nmap));
170 }
171 
172 iopreset()
173 {
174 	register struct cdevsw *cdp;
175 	int s;
176 
177 #ifdef CPU_DOUBLE
178 	s = spl6();
179 	printf("iop: reset");
180 	for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++)
181 		(*cdp->d_reset)();
182 	printf("\n");
183 	splx(s);
184 #endif
185 #ifdef CPU_SINGLE
186 	printf("hb: reset");
187 	for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++)
188 		(*cdp->d_reset)();
189 	printf("\n");
190 #endif
191 }
192 
193 #ifdef CPU_SINGLE
194 scsend(chan, flag, sc)
195 	int chan;
196 	int flag;
197 	struct scsi *sc;
198 {
199 	register int i;
200 
201 	sc_send(chan, flag, sc);
202 	if (flag & SCSI_NOTWAIT)
203 		return;
204 	if ((flag & SCSI_INTEN) == 0) {
205 		for (i = 0; i < 2000000; i++)
206 			if (!sc_busy(chan))
207 				return;
208 		printf("SCSI: scsend() timeout: intr=0x%x, ie=0x%x, sc=0x%x\n",
209 								chan, flag, sc);
210 	}
211 }
212 #endif /* CPU_SINGLE */
213 
214 #ifdef CPU_SINGLE
215 /*kos000*/
216 int
217 on_iobusintr2(func, arg, pri)
218 	int (*func)();
219 	int arg;
220 	int pri;
221 {
222 	register_hb_intr2(func, arg, pri);
223 }
224 
225 int
226 on_iobusintr4(func, arg, pri)
227 	int (*func)();
228 	int arg;
229 	int pri;
230 {
231 	register_hb_intr4(func, arg, pri);
232 }
233 /*kos000*/
234 
235 /*kos111*/
236 struct hb_intr {
237 	struct hb_intr *forw;
238 	struct hb_intr *back;
239 	int pri;
240 	int (*func)();
241 	int arg;
242 };
243 
244 struct hb_intr hb_intr2;
245 struct hb_intr hb_intr4;
246 
247 init_hb_intr()
248 {
249 	init_hb_intr2();
250 	init_hb_intr4();
251 }
252 
253 init_hb_intr2()
254 {
255 	hb_intr2.forw = hb_intr2.back = &hb_intr2;
256 	hb_intr2.pri = 32767;
257 	hb_intr2.func = 0;
258 	hb_intr2.arg = 0;
259 }
260 
261 init_hb_intr4()
262 {
263 	hb_intr4.forw = hb_intr4.back = &hb_intr4;
264 	hb_intr4.pri = 32767;
265 	hb_intr4.func = 0;
266 	hb_intr4.arg = 0;
267 }
268 
269 register_hb_intr2(func, arg, pri)
270 	int (*func)();
271 	int arg;
272 	int pri;
273 {
274 	register struct hb_intr *p, *q;
275 	register int s = splclock();
276 
277 	p = malloc(sizeof (struct hb_intr), M_DEVBUF, M_WAITOK);
278 	p->pri = pri;
279 	p->func = func;
280 	p->arg = arg;
281 
282 	for (q = hb_intr2.forw; q != &hb_intr2; q = q->forw)
283 		if (p->pri < q->pri)
284 			break;
285 	insque(p, q->back);
286 
287 	splx(s);
288 }
289 
290 unregister_hb_intr2(func)
291 	int (*func)();
292 {
293 	register struct hb_intr *p, *q;
294 	register int s = splclock();
295 
296 	for (p = hb_intr2.forw; p != &hb_intr2; p = p->forw) {
297 		if (p->func == func) {
298 			remque(p);
299 			free((caddr_t)p, M_DEVBUF);
300 			break;
301 		}
302 	}
303 
304 	splx(s);
305 }
306 
307 register_hb_intr4(func, arg, pri)
308 	int (*func)();
309 	int arg;
310 	int pri;
311 {
312 	register struct hb_intr *p, *q;
313 	register int s = splclock();
314 
315 	p = malloc(sizeof (struct hb_intr), M_DEVBUF, M_WAITOK);
316 	p->pri = pri;
317 	p->func = func;
318 	p->arg = arg;
319 
320 	for (q = hb_intr4.forw; q != &hb_intr4; q = q->forw)
321 		if (p->pri < q->pri)
322 			break;
323 	insque(p, q->back);
324 
325 	splx(s);
326 }
327 
328 unregister_hb_intr4(func)
329 	int (*func)();
330 {
331 	register struct hb_intr *p, *q;
332 	register int s = splclock();
333 
334 	for (p = hb_intr4.forw; p != &hb_intr4; p = p->forw) {
335 		if (p->func == func) {
336 			remque(p);
337 			free((caddr_t)p, M_DEVBUF);
338 			break;
339 		}
340 	}
341 
342 	splx(s);
343 }
344 
345 extern struct vmmeter cnt;
346 
347 exec_hb_intr2()
348 {
349 	register struct hb_intr *p;
350 
351 	for (p = hb_intr2.forw; p != &hb_intr2; p = p->forw) {
352 		if ((int)p->func == 0)
353 			goto out;
354 
355 		if ((*(p->func))(p->arg)) {
356 			cnt.v_intr++;	/* statistics info. */
357 			return;
358 		}
359 	}
360 out:
361 #ifdef news3400
362 	return;
363 #else
364 	printf("stray hb intr 2\n");
365 #endif
366 }
367 
368 exec_hb_intr4()
369 {
370 	register struct hb_intr *p;
371 
372 	for (p = hb_intr4.forw; p != &hb_intr4; p = p->forw) {
373 		if ((int)p->func == 0)
374 			goto out;
375 
376 		if ((*(p->func))(p->arg)) {
377 			cnt.v_intr++;	/* statistics info. */
378 			return;
379 		}
380 	}
381 out:
382 #ifdef news3400
383 	return;
384 #else
385 	printf("stray hb intr 4\n");
386 #endif
387 }
388 /*kos111*/
389 #endif /* CPU_SINGLE */
390