xref: /csrg-svn/sys/news3400/iop/iop.c (revision 63308)
153887Smckusick /*
2*63308Sbostic  * Copyright (c) 1992, 1993
3*63308Sbostic  *	The Regents of the University of California.  All rights reserved.
453887Smckusick  *
553887Smckusick  * This code is derived from software contributed to Berkeley by
653887Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753887Smckusick  *
853887Smckusick  * %sccs.include.redist.c%
953887Smckusick  *
1053887Smckusick  * from: $Hdr: iop.c,v 4.300 91/06/09 06:42:37 root Rel41 $ SONY
1153887Smckusick  *
12*63308Sbostic  *	@(#)iop.c	8.1 (Berkeley) 06/11/93
1353887Smckusick  */
1453887Smckusick 
1553887Smckusick /*
1653887Smckusick  *	iop.c / hb.c	ver 0.0
1753887Smckusick  */
1853887Smckusick 
1957183Sutashiro #include <machine/machConst.h>
2053887Smckusick 
2157183Sutashiro #include <sys/param.h>
2257183Sutashiro #include <sys/systm.h>
2357183Sutashiro #include <sys/map.h>
2457183Sutashiro #include <sys/buf.h>
2557183Sutashiro #include <sys/proc.h>
2657183Sutashiro #include <sys/user.h>
2757183Sutashiro #include <sys/conf.h>
2857183Sutashiro #include <sys/dkstat.h>
2957183Sutashiro #include <sys/kernel.h>
3057183Sutashiro #include <sys/malloc.h>
3153887Smckusick 
3257183Sutashiro #include <machine/pte.h>
3357183Sutashiro #include <machine/cpu.h>
3453887Smckusick 
3557183Sutashiro #include <news3400/iodev/scsireg.h>
3653887Smckusick 
3753887Smckusick #ifdef CPU_DOUBLE
3853887Smckusick #include "../iop/iopvar.h"
3953887Smckusick #endif
4053887Smckusick 
4153887Smckusick #ifdef CPU_SINGLE
4257183Sutashiro #include <news3400/hbdev/hbvar.h>
4357183Sutashiro #include <news3400/hbdev/scsic.h>
4453887Smckusick struct scsi_stat scsi_stat;
4553887Smckusick #endif
4653887Smckusick 
4753887Smckusick /*
4853887Smckusick  * dual processor ===> single processor
4953887Smckusick  */
5053887Smckusick #ifdef CPU_SINGLE
5153887Smckusick # define	iopreset	hbreset
5253887Smckusick # define	iopbuf		hbbuf
5353887Smckusick # define	iopalloc	hballoc
5453887Smckusick # define	iopsetup	hbsetup
5553887Smckusick # define	iop_ctlr	hb_ctlr
5653887Smckusick # define	iop_device	hb_device
5753887Smckusick # define	iopgo		hbgo
5853887Smckusick 
5953887Smckusick # define	im_driver	hm_driver
6053887Smckusick # define	im_ctlr		hm_ctlr
6153887Smckusick # define	im_alive	hm_alive
6253887Smckusick # define	im_addr		hm_addr
6353887Smckusick # define	im_intr		hm_intr
6453887Smckusick # define	im_scnum	hm_scnum
6553887Smckusick # define	im_hd		hm_hd
6653887Smckusick # define	im_hbinfo	hm_hbinfo
6753887Smckusick # define	im_tab		hm_tab
6853887Smckusick 
6953887Smckusick # define	ii_driver	hi_driver
7053887Smckusick # define	ii_unit		hi_unit
7153887Smckusick # define	ii_ctlr		hi_ctlr
7253887Smckusick # define	ii_slave	hi_slave
7353887Smckusick # define	ii_addr		hi_addr
7453887Smckusick # define	ii_intr		hi_intr
7553887Smckusick # define	ii_dk		hi_dk
7653887Smckusick # define	ii_flags	hi_flags
7753887Smckusick # define	ii_alive	hi_alive
7853887Smckusick # define	ii_type		hi_type
7953887Smckusick # define	ii_forw		hi_forw
8053887Smckusick # define	ii_mi		hi_mi
8153887Smckusick # define	ii_hd		hi_hd
8253887Smckusick 
8353887Smckusick # define	id_dgo		hd_dgo
8453887Smckusick #endif /* CPU_SINGLE */
8553887Smckusick 
iopgo(ii,map)8653887Smckusick iopgo(ii, map)
8753887Smckusick 	register struct iop_device *ii;
8853887Smckusick 	struct sc_map *map;
8953887Smckusick {
9053887Smckusick 	register struct iop_ctlr *im = ii->ii_mi;
9153887Smckusick 	register int unit;
9253887Smckusick 	int s;
9353887Smckusick 
9453887Smckusick 	s = spl6();
9553887Smckusick 	if (map)
9653887Smckusick 		(void)iopsetup(im->im_tab.b_actf->b_actf, map, NSCMAP);
9753887Smckusick 	splx(s);
9853887Smckusick 	if (ii->ii_dk >= 0) {
9953887Smckusick 		unit = ii->ii_dk;
10053887Smckusick 		dk_busy |= 1<<unit;
10153887Smckusick 		dk_xfer[unit]++;
10253887Smckusick 		dk_wds[unit] += im->im_tab.b_actf->b_actf->b_bcount>>6;
10353887Smckusick 	}
10453887Smckusick 	if (im->im_driver->id_dgo)
10553887Smckusick 		(*im->im_driver->id_dgo)(im);
10653887Smckusick }
10753887Smckusick 
iopsetup(bp,map,nmap)10853887Smckusick iopsetup(bp, map, nmap)
10953887Smckusick 	register struct buf *bp;
11053887Smckusick 	struct sc_map *map;
11153887Smckusick 	int nmap;
11253887Smckusick {
11353887Smckusick 	register struct pte *pte;
11453887Smckusick 	register unsigned *io;
11553887Smckusick 	int o, npf;
11653887Smckusick 
11753887Smckusick 	o = (int)bp->b_un.b_addr & PGOFSET;
11853887Smckusick 	map->mp_offset = o;
11953887Smckusick 	npf = btoc(bp->b_bcount + o);
12053887Smckusick 	if (npf > nmap)
12153887Smckusick 		panic("sc_map setup: bcount too large");
12253887Smckusick 	map->mp_pages = npf;
12353887Smckusick 	io = map->mp_addr;
12453887Smckusick #ifdef mips
12553887Smckusick 	if (MACH_IS_UNMAPPED(bp->b_un.b_addr)) {
12653887Smckusick 		int	i;
12753887Smckusick 
12853887Smckusick 		for (i = 0; npf-- > 0; i++)
12953887Smckusick 			*io++ = ((MACH_UNMAPPED_TO_PHYS(bp->b_un.b_addr))
13053887Smckusick 				 >> PGSHIFT) + i;
13153887Smckusick 		return (1);
13253887Smckusick 	}
13353887Smckusick 	else if ((bp->b_un.b_addr >= (caddr_t)VM_MIN_KERNEL_ADDRESS) &&
13453887Smckusick 		 (bp->b_un.b_addr < (caddr_t)VM_MAX_KERNEL_ADDRESS)) {
13553887Smckusick 		pte = (struct pte*)kvtopte(bp->b_un.b_addr);
13653887Smckusick 		while (--npf >= 0) {
13753887Smckusick 			if (pte->pg_pfnum == 0)
13853887Smckusick 				panic("sc_map setup: zero pfnum");
13953887Smckusick 			*io++ = pte++->pg_pfnum;
14053887Smckusick 		}
14153887Smckusick 		return (1);
14253887Smckusick 	}
14353887Smckusick 	else {
14453887Smckusick 		panic("iopsetup: user address is not allowed");
14553887Smckusick 	}
14653887Smckusick #else /* mips */
14760004Sutashiro 	ERROR!  This code does not work. /* KU:XXX */
14853887Smckusick 	pte = buftopte(bp);
14953887Smckusick 	while (--npf >= 0) {
15053887Smckusick 		if (pte->pg_pfnum == 0)
15153887Smckusick 			panic("sc_map setup: zero pfnum");
15253887Smckusick 		*io++ = pte++->pg_pfnum;
15353887Smckusick 	}
15453887Smckusick 	return (1);
15553887Smckusick #endif /* mips */
15653887Smckusick }
15753887Smckusick 
iopalloc(addr,bcnt,map,nmap)15853887Smckusick iopalloc(addr, bcnt, map, nmap)
15953887Smckusick 	caddr_t addr;
16053887Smckusick 	int bcnt, nmap;
16153887Smckusick 	struct sc_map *map;
16253887Smckusick {
16353887Smckusick 	struct buf iopbuf;
16453887Smckusick 
16553887Smckusick 	iopbuf.b_un.b_addr = addr;
16653887Smckusick 	iopbuf.b_flags = B_BUSY;
16753887Smckusick 	iopbuf.b_bcount = bcnt;
16853887Smckusick 	/* that's all the fields iopsetup() needs */
16953887Smckusick 	return (iopsetup(&iopbuf, map, nmap));
17053887Smckusick }
17153887Smckusick 
iopreset()17253887Smckusick iopreset()
17353887Smckusick {
17453887Smckusick 	register struct cdevsw *cdp;
17553887Smckusick 	int s;
17653887Smckusick 
17753887Smckusick #ifdef CPU_DOUBLE
17853887Smckusick 	s = spl6();
17953887Smckusick 	printf("iop: reset");
18053887Smckusick 	for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++)
18153887Smckusick 		(*cdp->d_reset)();
18253887Smckusick 	printf("\n");
18353887Smckusick 	splx(s);
18453887Smckusick #endif
18553887Smckusick #ifdef CPU_SINGLE
18653887Smckusick 	printf("hb: reset");
18753887Smckusick 	for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++)
18853887Smckusick 		(*cdp->d_reset)();
18953887Smckusick 	printf("\n");
19053887Smckusick #endif
19153887Smckusick }
19253887Smckusick 
19353887Smckusick #ifdef CPU_SINGLE
scsend(chan,flag,sc)19453887Smckusick scsend(chan, flag, sc)
19553887Smckusick 	int chan;
19653887Smckusick 	int flag;
19753887Smckusick 	struct scsi *sc;
19853887Smckusick {
19953887Smckusick 	register int i;
20053887Smckusick 
20153887Smckusick 	sc_send(chan, flag, sc);
20253887Smckusick 	if (flag & SCSI_NOTWAIT)
20353887Smckusick 		return;
20453887Smckusick 	if ((flag & SCSI_INTEN) == 0) {
20553887Smckusick 		for (i = 0; i < 2000000; i++)
20653887Smckusick 			if (!sc_busy(chan))
20753887Smckusick 				return;
20853887Smckusick 		printf("SCSI: scsend() timeout: intr=0x%x, ie=0x%x, sc=0x%x\n",
20953887Smckusick 								chan, flag, sc);
21053887Smckusick 	}
21153887Smckusick }
21253887Smckusick #endif /* CPU_SINGLE */
21353887Smckusick 
21453887Smckusick #ifdef CPU_SINGLE
21553887Smckusick /*kos000*/
21653887Smckusick int
21753887Smckusick on_iobusintr2(func, arg, pri)
21853887Smckusick 	int (*func)();
21953887Smckusick 	int arg;
22053887Smckusick 	int pri;
22153887Smckusick {
22253887Smckusick 	register_hb_intr2(func, arg, pri);
22353887Smckusick }
22453887Smckusick 
22553887Smckusick int
22653887Smckusick on_iobusintr4(func, arg, pri)
22753887Smckusick 	int (*func)();
22853887Smckusick 	int arg;
22953887Smckusick 	int pri;
23053887Smckusick {
23153887Smckusick 	register_hb_intr4(func, arg, pri);
23253887Smckusick }
23353887Smckusick /*kos000*/
23453887Smckusick 
23553887Smckusick /*kos111*/
23653887Smckusick struct hb_intr {
23753887Smckusick 	struct hb_intr *forw;
23853887Smckusick 	struct hb_intr *back;
23953887Smckusick 	int pri;
24053887Smckusick 	int (*func)();
24153887Smckusick 	int arg;
24253887Smckusick };
24353887Smckusick 
24453887Smckusick struct hb_intr hb_intr2;
24553887Smckusick struct hb_intr hb_intr4;
24653887Smckusick 
init_hb_intr()24753887Smckusick init_hb_intr()
24853887Smckusick {
24953887Smckusick 	init_hb_intr2();
25053887Smckusick 	init_hb_intr4();
25153887Smckusick }
25253887Smckusick 
init_hb_intr2()25353887Smckusick init_hb_intr2()
25453887Smckusick {
25553887Smckusick 	hb_intr2.forw = hb_intr2.back = &hb_intr2;
25653887Smckusick 	hb_intr2.pri = 32767;
25753887Smckusick 	hb_intr2.func = 0;
25853887Smckusick 	hb_intr2.arg = 0;
25953887Smckusick }
26053887Smckusick 
init_hb_intr4()26153887Smckusick init_hb_intr4()
26253887Smckusick {
26353887Smckusick 	hb_intr4.forw = hb_intr4.back = &hb_intr4;
26453887Smckusick 	hb_intr4.pri = 32767;
26553887Smckusick 	hb_intr4.func = 0;
26653887Smckusick 	hb_intr4.arg = 0;
26753887Smckusick }
26853887Smckusick 
26953887Smckusick register_hb_intr2(func, arg, pri)
27053887Smckusick 	int (*func)();
27153887Smckusick 	int arg;
27253887Smckusick 	int pri;
27353887Smckusick {
27453887Smckusick 	register struct hb_intr *p, *q;
27553887Smckusick 	register int s = splclock();
27653887Smckusick 
27753887Smckusick 	p = malloc(sizeof (struct hb_intr), M_DEVBUF, M_WAITOK);
27853887Smckusick 	p->pri = pri;
27953887Smckusick 	p->func = func;
28053887Smckusick 	p->arg = arg;
28153887Smckusick 
28253887Smckusick 	for (q = hb_intr2.forw; q != &hb_intr2; q = q->forw)
28353887Smckusick 		if (p->pri < q->pri)
28453887Smckusick 			break;
28553887Smckusick 	insque(p, q->back);
28653887Smckusick 
28753887Smckusick 	splx(s);
28853887Smckusick }
28953887Smckusick 
29053887Smckusick unregister_hb_intr2(func)
29153887Smckusick 	int (*func)();
29253887Smckusick {
29353887Smckusick 	register struct hb_intr *p, *q;
29453887Smckusick 	register int s = splclock();
29553887Smckusick 
29653887Smckusick 	for (p = hb_intr2.forw; p != &hb_intr2; p = p->forw) {
29753887Smckusick 		if (p->func == func) {
29853887Smckusick 			remque(p);
29953887Smckusick 			free((caddr_t)p, M_DEVBUF);
30053887Smckusick 			break;
30153887Smckusick 		}
30253887Smckusick 	}
30353887Smckusick 
30453887Smckusick 	splx(s);
30553887Smckusick }
30653887Smckusick 
30753887Smckusick register_hb_intr4(func, arg, pri)
30853887Smckusick 	int (*func)();
30953887Smckusick 	int arg;
31053887Smckusick 	int pri;
31153887Smckusick {
31253887Smckusick 	register struct hb_intr *p, *q;
31353887Smckusick 	register int s = splclock();
31453887Smckusick 
31553887Smckusick 	p = malloc(sizeof (struct hb_intr), M_DEVBUF, M_WAITOK);
31653887Smckusick 	p->pri = pri;
31753887Smckusick 	p->func = func;
31853887Smckusick 	p->arg = arg;
31953887Smckusick 
32053887Smckusick 	for (q = hb_intr4.forw; q != &hb_intr4; q = q->forw)
32153887Smckusick 		if (p->pri < q->pri)
32253887Smckusick 			break;
32353887Smckusick 	insque(p, q->back);
32453887Smckusick 
32553887Smckusick 	splx(s);
32653887Smckusick }
32753887Smckusick 
32853887Smckusick unregister_hb_intr4(func)
32953887Smckusick 	int (*func)();
33053887Smckusick {
33153887Smckusick 	register struct hb_intr *p, *q;
33253887Smckusick 	register int s = splclock();
33353887Smckusick 
33453887Smckusick 	for (p = hb_intr4.forw; p != &hb_intr4; p = p->forw) {
33553887Smckusick 		if (p->func == func) {
33653887Smckusick 			remque(p);
33753887Smckusick 			free((caddr_t)p, M_DEVBUF);
33853887Smckusick 			break;
33953887Smckusick 		}
34053887Smckusick 	}
34153887Smckusick 
34253887Smckusick 	splx(s);
34353887Smckusick }
34453887Smckusick 
34553887Smckusick extern struct vmmeter cnt;
34653887Smckusick 
exec_hb_intr2()34753887Smckusick exec_hb_intr2()
34853887Smckusick {
34953887Smckusick 	register struct hb_intr *p;
35053887Smckusick 
35153887Smckusick 	for (p = hb_intr2.forw; p != &hb_intr2; p = p->forw) {
35253887Smckusick 		if ((int)p->func == 0)
35353887Smckusick 			goto out;
35453887Smckusick 
35553887Smckusick 		if ((*(p->func))(p->arg)) {
35653887Smckusick 			cnt.v_intr++;	/* statistics info. */
35753887Smckusick 			return;
35853887Smckusick 		}
35953887Smckusick 	}
36053887Smckusick out:
36153887Smckusick #ifdef news3400
36253887Smckusick 	return;
36353887Smckusick #else
36453887Smckusick 	printf("stray hb intr 2\n");
36553887Smckusick #endif
36653887Smckusick }
36753887Smckusick 
exec_hb_intr4()36853887Smckusick exec_hb_intr4()
36953887Smckusick {
37053887Smckusick 	register struct hb_intr *p;
37153887Smckusick 
37253887Smckusick 	for (p = hb_intr4.forw; p != &hb_intr4; p = p->forw) {
37353887Smckusick 		if ((int)p->func == 0)
37453887Smckusick 			goto out;
37553887Smckusick 
37653887Smckusick 		if ((*(p->func))(p->arg)) {
37753887Smckusick 			cnt.v_intr++;	/* statistics info. */
37853887Smckusick 			return;
37953887Smckusick 		}
38053887Smckusick 	}
38153887Smckusick out:
38253887Smckusick #ifdef news3400
38353887Smckusick 	return;
38453887Smckusick #else
38553887Smckusick 	printf("stray hb intr 4\n");
38653887Smckusick #endif
38753887Smckusick }
38853887Smckusick /*kos111*/
38953887Smckusick #endif /* CPU_SINGLE */
390