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