153901Smckusick /* 253901Smckusick * Copyright (c) 1992 The Regents of the University of California. 353901Smckusick * All rights reserved. 453901Smckusick * 553901Smckusick * This code is derived from software contributed to Berkeley by 653901Smckusick * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 753901Smckusick * 853901Smckusick * %sccs.include.redist.c% 953901Smckusick * 1053901Smckusick * from: $Hdr: psd.c,v 4.300 91/06/09 06:38:07 root Rel41 $ SONY 1153901Smckusick * 12*58617Sutashiro * @(#)psd.c 7.3 (Berkeley) 03/09/93 1353901Smckusick */ 1453901Smckusick 1553901Smckusick /* 1653901Smckusick * Copyright (c) 1987, 1988 by SONY Corporation. 1753901Smckusick */ 1853901Smckusick 1953901Smckusick /* 2053901Smckusick * psd.c ver 1.0 2153901Smckusick * Fri Mar 31 16:01:42 JST 1989 2253901Smckusick * 2353901Smckusick * Probe SCSI device routine 2453901Smckusick * 2553901Smckusick */ 2653901Smckusick 2757182Sutashiro #include <sys/param.h> 2857182Sutashiro #include <sys/buf.h> 2957182Sutashiro #include <sys/proc.h> 3057182Sutashiro #include <sys/user.h> 3157182Sutashiro #include <sys/dkstat.h> 3257182Sutashiro #include <sys/uio.h> 3357182Sutashiro #include <sys/kernel.h> 3457182Sutashiro #include <sys/ioctl.h> 3557182Sutashiro #include <sys/syslog.h> 3653901Smckusick 3757182Sutashiro #include <vm/vm.h> 3853901Smckusick 3953901Smckusick #ifdef mips 4057182Sutashiro #include <machine/cpu.h> 4153901Smckusick #endif 4253901Smckusick 4353901Smckusick #ifdef IPC_MRX 4453901Smckusick #include "../iop/iopvar.h" 4553901Smckusick #include "../ipc/newsipc.h" 4653901Smckusick #endif 4753901Smckusick 4853901Smckusick #ifdef CPU_SINGLE 4957182Sutashiro #include <news3400/hbdev/hbvar.h> 5057182Sutashiro #include <news3400/hbdev/scsic.h> 5153901Smckusick #endif 5253901Smckusick 5357182Sutashiro #include <news3400/iodev/scsireg.h> 5457182Sutashiro #include <news3400/iodev/scu.h> 5553901Smckusick 5657182Sutashiro #include <news3400/iodev/ioptohb.h> 5753901Smckusick 5853901Smckusick 5953901Smckusick #define PROBE_MAXRETRY 100 6053901Smckusick #define NRETRY 10 6153901Smckusick #define MAXHRDERR 100 6253901Smckusick #define NSCSICHAN 7 6353901Smckusick 6453901Smckusick #define NOSUCHDEV 0x7f 6553901Smckusick 6653901Smckusick #ifdef news3400 6753901Smckusick #define MAXCTLR 8 6853901Smckusick #endif 6953901Smckusick 7053901Smckusick #ifdef news3800 7153901Smckusick #define MAXCTLR 16 7253901Smckusick #endif 7353901Smckusick 7453901Smckusick #define MAXSLAVE 8 7553901Smckusick 7653901Smckusick struct scsi scsi[MAXCTLR]; 7753901Smckusick struct sc_map scmap[MAXCTLR]; 7853901Smckusick struct sc_inq scinq[MAXCTLR]; 7953901Smckusick 8053901Smckusick #ifdef IPC_MRX 8153901Smckusick extern int port_scsi; /* UNIX port of SCSI */ 8253901Smckusick extern int iop_scsi[]; /* IOP port of SCSI process */ 8353901Smckusick #endif 8453901Smckusick 8553901Smckusick #ifdef CPU_DOUBLE 8653901Smckusick extern struct scintsw scintsw[]; 8753901Smckusick #endif 8853901Smckusick 8953901Smckusick /* 9053901Smckusick * Universal SCSI probe routine 9153901Smckusick * for mass storage controller. 9253901Smckusick */ 9353901Smckusick psdprobe(im) 9453901Smckusick register struct iop/**/_ctlr *im; 9553901Smckusick { 9653901Smckusick register int intr = im->im_intr; 9753901Smckusick struct scintsw *sci; 9853901Smckusick int ctlrintr; 9953901Smckusick int j; 10053901Smckusick char name[16]; 10153901Smckusick register struct sc_inq *inq = &scinq[intr]; 10253901Smckusick 10353901Smckusick #ifdef IPC_MRX 10453901Smckusick int scintr(); 10553901Smckusick 10653901Smckusick if (port_scsi == 0) { 10753901Smckusick port_scsi = port_create("@scsi", scintr, -1); 10853901Smckusick for(j = 0; j < MAXCTLR; j++) { 10953901Smckusick if(j == 7 || j == 15) 11053901Smckusick continue; 11153901Smckusick iop_scsi[j] = object_query(make_name(name, "scsiportXX", j)); 11253901Smckusick } 11353901Smckusick } 11453901Smckusick #endif /* IPC_MRX */ 11553901Smckusick sci = &scintsw[intr]; 11653901Smckusick if (sci->sci_inthandler) { 11753901Smckusick /* 11853901Smckusick * already probed. 11953901Smckusick */ 12053901Smckusick return (-1); 12153901Smckusick } 12253901Smckusick 12353901Smckusick /* 12453901Smckusick * probe device product ID 12553901Smckusick * & set driver interrupt handler 12653901Smckusick */ 12753901Smckusick if (probe_inq(im, inq) == 0) { 12853901Smckusick /* 12953901Smckusick * inquiry command terminate with bad status 13053901Smckusick * set 0x7f(Specified device is nonexistent) to devtype 13153901Smckusick */ 13253901Smckusick inq->sci_devtype = NOSUCHDEV; 13353901Smckusick } 13453901Smckusick return (inq->sci_devtype); 13553901Smckusick } 13653901Smckusick 13753901Smckusick set_inthandler(im, handler) 13853901Smckusick register struct iop/**/_ctlr *im; 13953901Smckusick int (*handler)(); 14053901Smckusick { 14153901Smckusick struct scintsw *sci; 14253901Smckusick 14353901Smckusick sci = &scintsw[im->im_intr]; 14453901Smckusick if (sci->sci_inthandler) 14553901Smckusick return (0); /* already probed. */ 14653901Smckusick 14753901Smckusick sci->sci_inthandler = handler; 14853901Smckusick sci->sci_ctlr = im->im_ctlr; 14953901Smckusick return (1); 15053901Smckusick } 15153901Smckusick 15253901Smckusick probe_inq(im, inq) 15353901Smckusick register struct iop/**/_ctlr *im; 15453901Smckusick register struct sc_inq *inq; 15553901Smckusick { 15653901Smckusick register int intr = im->im_intr; 15753901Smckusick register struct scsi *sc = &scsi[intr]; 15853901Smckusick register int retry = 0; 15953901Smckusick 16053901Smckusick bzero(inq, sizeof(struct sc_inq)); 16153901Smckusick 16253901Smckusick psdprobe_loop: 16353901Smckusick 16453901Smckusick scop_inquiry(intr, sc, 0, SCSI_INTDIS, sizeof(struct sc_inq), inq); 16553901Smckusick 16653901Smckusick if (sc->sc_istatus != INST_EP) { 16753901Smckusick /* 16853901Smckusick * probe fault. 16953901Smckusick */ 17053901Smckusick if (sc->sc_istatus == (INST_EP|INST_HE)) { 17153901Smckusick /* 17253901Smckusick * bus reset, retry 17353901Smckusick */ 17453901Smckusick goto psdprobe_loop; 17553901Smckusick } 17653901Smckusick return (0); 17753901Smckusick } 17853901Smckusick #ifndef NO_STATUS_BYTE_MASK 17953901Smckusick sc->sc_tstatus &= TGSTMASK; 180*58617Sutashiro #endif 18153901Smckusick if (sc->sc_tstatus != TGST_GOOD) { 18253901Smckusick if (sc->sc_tstatus == TGST_CC) 18353901Smckusick scop_rsense(intr, sc, 0, SCSI_INTDIS, 18, 0); 18453901Smckusick if (retry++ < PROBE_MAXRETRY) { 18553901Smckusick DELAY(600000); /* XXX 1 sec */ 18653901Smckusick goto psdprobe_loop; 18753901Smckusick } 18853901Smckusick /* 18953901Smckusick * probe fault. 19053901Smckusick */ 19153901Smckusick return (0); 19253901Smckusick } 19353901Smckusick return (1); 19453901Smckusick } 19553901Smckusick 19653901Smckusick struct scsi * 19753901Smckusick get_scsi(intr) 19853901Smckusick int intr; 19953901Smckusick { 20053901Smckusick return (&scsi[intr]); 20153901Smckusick } 20253901Smckusick 20353901Smckusick struct sc_map * 20453901Smckusick get_sc_map(intr) 20553901Smckusick int intr; 20653901Smckusick { 20753901Smckusick return (&scmap[intr]); 20853901Smckusick } 20953901Smckusick 21053901Smckusick struct sc_inq * 21153901Smckusick get_sc_inq(intr) 21253901Smckusick int intr; 21353901Smckusick { 21453901Smckusick return (&scinq[intr]); 21553901Smckusick } 216