1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. 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 8.1 (Berkeley) 06/11/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 */
psdprobe(im)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
set_inthandler(im,handler)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
probe_inq(im,inq)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 *
get_scsi(intr)197 get_scsi(intr)
198 int intr;
199 {
200 return (&scsi[intr]);
201 }
202
203 struct sc_map *
get_sc_map(intr)204 get_sc_map(intr)
205 int intr;
206 {
207 return (&scmap[intr]);
208 }
209
210 struct sc_inq *
get_sc_inq(intr)211 get_sc_inq(intr)
212 int intr;
213 {
214 return (&scinq[intr]);
215 }
216