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