xref: /csrg-svn/sys/news3400/iodev/psd.c (revision 63307)
153901Smckusick /*
2*63307Sbostic  * Copyright (c) 1992, 1993
3*63307Sbostic  *	The Regents of the University of California.  All rights reserved.
453901Smckusick  *
553901Smckusick  * This code is derived from software contributed to Berkeley by
653901Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753901Smckusick  *
853901Smckusick  * %sccs.include.redist.c%
953901Smckusick  *
1053901Smckusick  * from: $Hdr: psd.c,v 4.300 91/06/09 06:38:07 root Rel41 $ SONY
1153901Smckusick  *
12*63307Sbostic  *	@(#)psd.c	8.1 (Berkeley) 06/11/93
1353901Smckusick  */
1453901Smckusick 
1553901Smckusick /*
1653901Smckusick  * Copyright (c) 1987, 1988 by SONY Corporation.
1753901Smckusick  */
1853901Smckusick 
1953901Smckusick /*
2053901Smckusick  * psd.c	ver 1.0
2153901Smckusick  *			Fri Mar 31 16:01:42 JST 1989
2253901Smckusick  *
2353901Smckusick  * Probe SCSI device routine
2453901Smckusick  *
2553901Smckusick  */
2653901Smckusick 
2757182Sutashiro #include <sys/param.h>
2857182Sutashiro #include <sys/buf.h>
2957182Sutashiro #include <sys/proc.h>
3057182Sutashiro #include <sys/user.h>
3157182Sutashiro #include <sys/dkstat.h>
3257182Sutashiro #include <sys/uio.h>
3357182Sutashiro #include <sys/kernel.h>
3457182Sutashiro #include <sys/ioctl.h>
3557182Sutashiro #include <sys/syslog.h>
3653901Smckusick 
3757182Sutashiro #include <vm/vm.h>
3853901Smckusick 
3953901Smckusick #ifdef mips
4057182Sutashiro #include <machine/cpu.h>
4153901Smckusick #endif
4253901Smckusick 
4353901Smckusick #ifdef IPC_MRX
4453901Smckusick #include "../iop/iopvar.h"
4553901Smckusick #include "../ipc/newsipc.h"
4653901Smckusick #endif
4753901Smckusick 
4853901Smckusick #ifdef CPU_SINGLE
4957182Sutashiro #include <news3400/hbdev/hbvar.h>
5057182Sutashiro #include <news3400/hbdev/scsic.h>
5153901Smckusick #endif
5253901Smckusick 
5357182Sutashiro #include <news3400/iodev/scsireg.h>
5457182Sutashiro #include <news3400/iodev/scu.h>
5553901Smckusick 
5657182Sutashiro #include <news3400/iodev/ioptohb.h>
5753901Smckusick 
5853901Smckusick 
5953901Smckusick #define	PROBE_MAXRETRY	100
6053901Smckusick #define	NRETRY		10
6153901Smckusick #define	MAXHRDERR	100
6253901Smckusick #define	NSCSICHAN	7
6353901Smckusick 
6453901Smckusick #define	NOSUCHDEV	0x7f
6553901Smckusick 
6653901Smckusick #ifdef news3400
6753901Smckusick #define	MAXCTLR		8
6853901Smckusick #endif
6953901Smckusick 
7053901Smckusick #ifdef news3800
7153901Smckusick #define	MAXCTLR		16
7253901Smckusick #endif
7353901Smckusick 
7453901Smckusick #define	MAXSLAVE	8
7553901Smckusick 
7653901Smckusick struct scsi scsi[MAXCTLR];
7753901Smckusick struct sc_map scmap[MAXCTLR];
7853901Smckusick struct sc_inq scinq[MAXCTLR];
7953901Smckusick 
8053901Smckusick #ifdef IPC_MRX
8153901Smckusick extern int port_scsi;		/* UNIX port of SCSI */
8253901Smckusick extern int iop_scsi[];		/* IOP port of SCSI process */
8353901Smckusick #endif
8453901Smckusick 
8553901Smckusick #ifdef CPU_DOUBLE
8653901Smckusick extern struct scintsw scintsw[];
8753901Smckusick #endif
8853901Smckusick 
8953901Smckusick /*
9053901Smckusick  * Universal SCSI probe routine
9153901Smckusick  *	for mass storage controller.
9253901Smckusick  */
psdprobe(im)9353901Smckusick psdprobe(im)
9453901Smckusick 	register struct iop/**/_ctlr *im;
9553901Smckusick {
9653901Smckusick 	register int intr = im->im_intr;
9753901Smckusick 	struct scintsw *sci;
9853901Smckusick 	int ctlrintr;
9953901Smckusick 	int j;
10053901Smckusick 	char name[16];
10153901Smckusick 	register struct sc_inq *inq = &scinq[intr];
10253901Smckusick 
10353901Smckusick #ifdef IPC_MRX
10453901Smckusick 	int scintr();
10553901Smckusick 
10653901Smckusick 	if (port_scsi == 0) {
10753901Smckusick 		port_scsi = port_create("@scsi", scintr, -1);
10853901Smckusick 		for(j = 0; j < MAXCTLR; j++) {
10953901Smckusick 			if(j == 7 || j == 15)
11053901Smckusick 				continue;
11153901Smckusick 			iop_scsi[j] = object_query(make_name(name, "scsiportXX", j));
11253901Smckusick 		}
11353901Smckusick 	}
11453901Smckusick #endif /* IPC_MRX */
11553901Smckusick 	sci = &scintsw[intr];
11653901Smckusick 	if (sci->sci_inthandler) {
11753901Smckusick 		/*
11853901Smckusick 		 * already probed.
11953901Smckusick 		 */
12053901Smckusick 		return (-1);
12153901Smckusick 	}
12253901Smckusick 
12353901Smckusick 	/*
12453901Smckusick 	 * probe device product ID
12553901Smckusick 	 *	& set driver interrupt handler
12653901Smckusick 	 */
12753901Smckusick 	if (probe_inq(im, inq) == 0) {
12853901Smckusick 		/*
12953901Smckusick 		 * inquiry command terminate with bad status
13053901Smckusick 		 *	set 0x7f(Specified device is nonexistent) to devtype
13153901Smckusick 		 */
13253901Smckusick 		inq->sci_devtype = NOSUCHDEV;
13353901Smckusick 	}
13453901Smckusick 	return (inq->sci_devtype);
13553901Smckusick }
13653901Smckusick 
set_inthandler(im,handler)13753901Smckusick set_inthandler(im, handler)
13853901Smckusick 	register struct iop/**/_ctlr *im;
13953901Smckusick 	int (*handler)();
14053901Smckusick {
14153901Smckusick 	struct scintsw *sci;
14253901Smckusick 
14353901Smckusick 	sci = &scintsw[im->im_intr];
14453901Smckusick 	if (sci->sci_inthandler)
14553901Smckusick 		return (0);	/* already probed. */
14653901Smckusick 
14753901Smckusick 	sci->sci_inthandler = handler;
14853901Smckusick 	sci->sci_ctlr = im->im_ctlr;
14953901Smckusick 	return (1);
15053901Smckusick }
15153901Smckusick 
probe_inq(im,inq)15253901Smckusick probe_inq(im, inq)
15353901Smckusick 	register struct iop/**/_ctlr *im;
15453901Smckusick 	register struct sc_inq *inq;
15553901Smckusick {
15653901Smckusick 	register int intr = im->im_intr;
15753901Smckusick 	register struct scsi *sc = &scsi[intr];
15853901Smckusick 	register int retry = 0;
15953901Smckusick 
16053901Smckusick 	bzero(inq, sizeof(struct sc_inq));
16153901Smckusick 
16253901Smckusick psdprobe_loop:
16353901Smckusick 
16453901Smckusick 	scop_inquiry(intr, sc, 0, SCSI_INTDIS, sizeof(struct sc_inq), inq);
16553901Smckusick 
16653901Smckusick 	if (sc->sc_istatus != INST_EP) {
16753901Smckusick 		/*
16853901Smckusick 		 * probe fault.
16953901Smckusick 		 */
17053901Smckusick 		if (sc->sc_istatus == (INST_EP|INST_HE)) {
17153901Smckusick 			/*
17253901Smckusick 			 * bus reset, retry
17353901Smckusick 			 */
17453901Smckusick 			goto psdprobe_loop;
17553901Smckusick 		}
17653901Smckusick 		return (0);
17753901Smckusick 	}
17853901Smckusick #ifndef NO_STATUS_BYTE_MASK
17953901Smckusick 	sc->sc_tstatus &= TGSTMASK;
18058617Sutashiro #endif
18153901Smckusick 	if (sc->sc_tstatus != TGST_GOOD) {
18253901Smckusick 		if (sc->sc_tstatus == TGST_CC)
18353901Smckusick 			scop_rsense(intr, sc, 0, SCSI_INTDIS, 18, 0);
18453901Smckusick 		if (retry++ < PROBE_MAXRETRY) {
18553901Smckusick 			DELAY(600000);		/* XXX  1 sec */
18653901Smckusick 			goto psdprobe_loop;
18753901Smckusick 		}
18853901Smckusick 		/*
18953901Smckusick 		 * probe fault.
19053901Smckusick 		 */
19153901Smckusick 		return (0);
19253901Smckusick 	}
19353901Smckusick 	return (1);
19453901Smckusick }
19553901Smckusick 
19653901Smckusick struct scsi *
get_scsi(intr)19753901Smckusick get_scsi(intr)
19853901Smckusick 	int	intr;
19953901Smckusick {
20053901Smckusick 	return (&scsi[intr]);
20153901Smckusick }
20253901Smckusick 
20353901Smckusick struct sc_map *
get_sc_map(intr)20453901Smckusick get_sc_map(intr)
20553901Smckusick 	int	intr;
20653901Smckusick {
20753901Smckusick 	return (&scmap[intr]);
20853901Smckusick }
20953901Smckusick 
21053901Smckusick struct sc_inq *
get_sc_inq(intr)21153901Smckusick get_sc_inq(intr)
21253901Smckusick 	int	intr;
21353901Smckusick {
21453901Smckusick 	return (&scinq[intr]);
21553901Smckusick }
216