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