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