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