xref: /csrg-svn/sys/news3400/iodev/psd.c (revision 53901)
1*53901Smckusick /*
2*53901Smckusick  * Copyright (c) 1992 The Regents of the University of California.
3*53901Smckusick  * All rights reserved.
4*53901Smckusick  *
5*53901Smckusick  * This code is derived from software contributed to Berkeley by
6*53901Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7*53901Smckusick  *
8*53901Smckusick  * %sccs.include.redist.c%
9*53901Smckusick  *
10*53901Smckusick  * from: $Hdr: psd.c,v 4.300 91/06/09 06:38:07 root Rel41 $ SONY
11*53901Smckusick  *
12*53901Smckusick  *	@(#)psd.c	7.1 (Berkeley) 06/04/92
13*53901Smckusick  */
14*53901Smckusick 
15*53901Smckusick /*
16*53901Smckusick  * Copyright (c) 1987, 1988 by SONY Corporation.
17*53901Smckusick  */
18*53901Smckusick 
19*53901Smckusick /*
20*53901Smckusick  * psd.c	ver 1.0
21*53901Smckusick  *			Fri Mar 31 16:01:42 JST 1989
22*53901Smckusick  *
23*53901Smckusick  * Probe SCSI device routine
24*53901Smckusick  *
25*53901Smckusick  */
26*53901Smckusick 
27*53901Smckusick #include "../include/fix_machine_type.h"
28*53901Smckusick 
29*53901Smckusick #include "param.h"
30*53901Smckusick #include "buf.h"
31*53901Smckusick #include "proc.h"
32*53901Smckusick #include "user.h"
33*53901Smckusick #include "dkstat.h"
34*53901Smckusick #include "uio.h"
35*53901Smckusick #include "kernel.h"
36*53901Smckusick #include "ioctl.h"
37*53901Smckusick #ifdef BSD4_3
38*53901Smckusick #include "syslog.h"
39*53901Smckusick #endif
40*53901Smckusick 
41*53901Smckusick #include "vm/vm.h"
42*53901Smckusick 
43*53901Smckusick #ifdef mips
44*53901Smckusick #include "../include/cpu.h"
45*53901Smckusick #endif
46*53901Smckusick 
47*53901Smckusick #ifdef IPC_MRX
48*53901Smckusick #include "../iop/iopvar.h"
49*53901Smckusick #include "../ipc/newsipc.h"
50*53901Smckusick #endif
51*53901Smckusick 
52*53901Smckusick #ifdef CPU_SINGLE
53*53901Smckusick #include "../hbdev/hbvar.h"
54*53901Smckusick #include "../hbdev/scsic.h"
55*53901Smckusick #endif
56*53901Smckusick 
57*53901Smckusick #include "../iodev/scsireg.h"
58*53901Smckusick #include "../iodev/scu.h"
59*53901Smckusick 
60*53901Smckusick #include "../iodev/ioptohb.h"
61*53901Smckusick 
62*53901Smckusick 
63*53901Smckusick #define	PROBE_MAXRETRY	100
64*53901Smckusick #define	NRETRY		10
65*53901Smckusick #define	MAXHRDERR	100
66*53901Smckusick #define	NSCSICHAN	7
67*53901Smckusick 
68*53901Smckusick #define	NOSUCHDEV	0x7f
69*53901Smckusick 
70*53901Smckusick #ifdef news800
71*53901Smckusick #define	MAXCTLR		8
72*53901Smckusick #endif
73*53901Smckusick 
74*53901Smckusick #ifdef news1200
75*53901Smckusick #define	MAXCTLR		8
76*53901Smckusick #endif
77*53901Smckusick 
78*53901Smckusick #ifdef news1700
79*53901Smckusick #define	MAXCTLR		8
80*53901Smckusick #endif
81*53901Smckusick 
82*53901Smckusick #ifdef news1800
83*53901Smckusick #define	MAXCTLR		8
84*53901Smckusick #endif
85*53901Smckusick 
86*53901Smckusick #ifdef news3400
87*53901Smckusick #define	MAXCTLR		8
88*53901Smckusick #endif
89*53901Smckusick 
90*53901Smckusick #ifdef news3800
91*53901Smckusick #define	MAXCTLR		16
92*53901Smckusick #endif
93*53901Smckusick 
94*53901Smckusick #define	MAXSLAVE	8
95*53901Smckusick 
96*53901Smckusick struct scsi scsi[MAXCTLR];
97*53901Smckusick struct sc_map scmap[MAXCTLR];
98*53901Smckusick struct sc_inq scinq[MAXCTLR];
99*53901Smckusick 
100*53901Smckusick #ifdef IPC_MRX
101*53901Smckusick extern int port_scsi;		/* UNIX port of SCSI */
102*53901Smckusick extern int iop_scsi[];		/* IOP port of SCSI process */
103*53901Smckusick #endif
104*53901Smckusick 
105*53901Smckusick #ifdef CPU_DOUBLE
106*53901Smckusick extern struct scintsw scintsw[];
107*53901Smckusick #endif
108*53901Smckusick 
109*53901Smckusick /*
110*53901Smckusick  * Universal SCSI probe routine
111*53901Smckusick  *	for mass storage controller.
112*53901Smckusick  */
113*53901Smckusick psdprobe(im)
114*53901Smckusick 	register struct iop/**/_ctlr *im;
115*53901Smckusick {
116*53901Smckusick 	register int intr = im->im_intr;
117*53901Smckusick 	struct scintsw *sci;
118*53901Smckusick 	int ctlrintr;
119*53901Smckusick 	int j;
120*53901Smckusick 	char name[16];
121*53901Smckusick 	register struct sc_inq *inq = &scinq[intr];
122*53901Smckusick 
123*53901Smckusick #ifdef IPC_MRX
124*53901Smckusick 	int scintr();
125*53901Smckusick 
126*53901Smckusick 	if (port_scsi == 0) {
127*53901Smckusick 		port_scsi = port_create("@scsi", scintr, -1);
128*53901Smckusick 		for(j = 0; j < MAXCTLR; j++) {
129*53901Smckusick 			if(j == 7 || j == 15)
130*53901Smckusick 				continue;
131*53901Smckusick 			iop_scsi[j] = object_query(make_name(name, "scsiportXX", j));
132*53901Smckusick 		}
133*53901Smckusick 	}
134*53901Smckusick #endif /* IPC_MRX */
135*53901Smckusick 	sci = &scintsw[intr];
136*53901Smckusick 	if (sci->sci_inthandler) {
137*53901Smckusick 		/*
138*53901Smckusick 		 * already probed.
139*53901Smckusick 		 */
140*53901Smckusick 		return (-1);
141*53901Smckusick 	}
142*53901Smckusick 
143*53901Smckusick 	/*
144*53901Smckusick 	 * probe device product ID
145*53901Smckusick 	 *	& set driver interrupt handler
146*53901Smckusick 	 */
147*53901Smckusick 	if (probe_inq(im, inq) == 0) {
148*53901Smckusick 		/*
149*53901Smckusick 		 * inquiry command terminate with bad status
150*53901Smckusick 		 *	set 0x7f(Specified device is nonexistent) to devtype
151*53901Smckusick 		 */
152*53901Smckusick 		inq->sci_devtype = NOSUCHDEV;
153*53901Smckusick 	}
154*53901Smckusick 	return (inq->sci_devtype);
155*53901Smckusick }
156*53901Smckusick 
157*53901Smckusick set_inthandler(im, handler)
158*53901Smckusick 	register struct iop/**/_ctlr *im;
159*53901Smckusick 	int (*handler)();
160*53901Smckusick {
161*53901Smckusick 	struct scintsw *sci;
162*53901Smckusick 
163*53901Smckusick 	sci = &scintsw[im->im_intr];
164*53901Smckusick 	if (sci->sci_inthandler)
165*53901Smckusick 		return (0);	/* already probed. */
166*53901Smckusick 
167*53901Smckusick 	sci->sci_inthandler = handler;
168*53901Smckusick 	sci->sci_ctlr = im->im_ctlr;
169*53901Smckusick 	return (1);
170*53901Smckusick }
171*53901Smckusick 
172*53901Smckusick probe_inq(im, inq)
173*53901Smckusick 	register struct iop/**/_ctlr *im;
174*53901Smckusick 	register struct sc_inq *inq;
175*53901Smckusick {
176*53901Smckusick 	register int intr = im->im_intr;
177*53901Smckusick 	register struct scsi *sc = &scsi[intr];
178*53901Smckusick 	register int retry = 0;
179*53901Smckusick 
180*53901Smckusick 	bzero(inq, sizeof(struct sc_inq));
181*53901Smckusick 
182*53901Smckusick psdprobe_loop:
183*53901Smckusick 
184*53901Smckusick 	scop_inquiry(intr, sc, 0, SCSI_INTDIS, sizeof(struct sc_inq), inq);
185*53901Smckusick 
186*53901Smckusick 	if (sc->sc_istatus != INST_EP) {
187*53901Smckusick 		/*
188*53901Smckusick 		 * probe fault.
189*53901Smckusick 		 */
190*53901Smckusick 		if (sc->sc_istatus == (INST_EP|INST_HE)) {
191*53901Smckusick 			/*
192*53901Smckusick 			 * bus reset, retry
193*53901Smckusick 			 */
194*53901Smckusick 			goto psdprobe_loop;
195*53901Smckusick 		}
196*53901Smckusick 		return (0);
197*53901Smckusick 	}
198*53901Smckusick #ifndef NO_STATUS_BYTE_MASK
199*53901Smckusick 	sc->sc_tstatus &= TGSTMASK;
200*53901Smckusick #endif /* !NO_STATUS_BYTE_MASK */
201*53901Smckusick 	if (sc->sc_tstatus != TGST_GOOD) {
202*53901Smckusick 		if (sc->sc_tstatus == TGST_CC)
203*53901Smckusick 			scop_rsense(intr, sc, 0, SCSI_INTDIS, 18, 0);
204*53901Smckusick 		if (retry++ < PROBE_MAXRETRY) {
205*53901Smckusick 			DELAY(600000);		/* XXX  1 sec */
206*53901Smckusick 			goto psdprobe_loop;
207*53901Smckusick 		}
208*53901Smckusick 		/*
209*53901Smckusick 		 * probe fault.
210*53901Smckusick 		 */
211*53901Smckusick 		return (0);
212*53901Smckusick 	}
213*53901Smckusick 	return (1);
214*53901Smckusick }
215*53901Smckusick 
216*53901Smckusick struct scsi *
217*53901Smckusick get_scsi(intr)
218*53901Smckusick 	int	intr;
219*53901Smckusick {
220*53901Smckusick 	return (&scsi[intr]);
221*53901Smckusick }
222*53901Smckusick 
223*53901Smckusick struct sc_map *
224*53901Smckusick get_sc_map(intr)
225*53901Smckusick 	int	intr;
226*53901Smckusick {
227*53901Smckusick 	return (&scmap[intr]);
228*53901Smckusick }
229*53901Smckusick 
230*53901Smckusick struct sc_inq *
231*53901Smckusick get_sc_inq(intr)
232*53901Smckusick 	int	intr;
233*53901Smckusick {
234*53901Smckusick 	return (&scinq[intr]);
235*53901Smckusick }
236