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