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