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*57182Sutashiro * @(#)psd.c 7.2 (Berkeley) 12/17/92 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 27*57182Sutashiro #include <machine/fix_machine_type.h> 2853901Smckusick 29*57182Sutashiro #include <sys/param.h> 30*57182Sutashiro #include <sys/buf.h> 31*57182Sutashiro #include <sys/proc.h> 32*57182Sutashiro #include <sys/user.h> 33*57182Sutashiro #include <sys/dkstat.h> 34*57182Sutashiro #include <sys/uio.h> 35*57182Sutashiro #include <sys/kernel.h> 36*57182Sutashiro #include <sys/ioctl.h> 37*57182Sutashiro #include <sys/syslog.h> 3853901Smckusick 39*57182Sutashiro #include <vm/vm.h> 4053901Smckusick 4153901Smckusick #ifdef mips 42*57182Sutashiro #include <machine/cpu.h> 4353901Smckusick #endif 4453901Smckusick 4553901Smckusick #ifdef IPC_MRX 4653901Smckusick #include "../iop/iopvar.h" 4753901Smckusick #include "../ipc/newsipc.h" 4853901Smckusick #endif 4953901Smckusick 5053901Smckusick #ifdef CPU_SINGLE 51*57182Sutashiro #include <news3400/hbdev/hbvar.h> 52*57182Sutashiro #include <news3400/hbdev/scsic.h> 5353901Smckusick #endif 5453901Smckusick 55*57182Sutashiro #include <news3400/iodev/scsireg.h> 56*57182Sutashiro #include <news3400/iodev/scu.h> 5753901Smckusick 58*57182Sutashiro #include <news3400/iodev/ioptohb.h> 5953901Smckusick 6053901Smckusick 6153901Smckusick #define PROBE_MAXRETRY 100 6253901Smckusick #define NRETRY 10 6353901Smckusick #define MAXHRDERR 100 6453901Smckusick #define NSCSICHAN 7 6553901Smckusick 6653901Smckusick #define NOSUCHDEV 0x7f 6753901Smckusick 6853901Smckusick #ifdef news800 6953901Smckusick #define MAXCTLR 8 7053901Smckusick #endif 7153901Smckusick 7253901Smckusick #ifdef news1200 7353901Smckusick #define MAXCTLR 8 7453901Smckusick #endif 7553901Smckusick 7653901Smckusick #ifdef news1700 7753901Smckusick #define MAXCTLR 8 7853901Smckusick #endif 7953901Smckusick 8053901Smckusick #ifdef news1800 8153901Smckusick #define MAXCTLR 8 8253901Smckusick #endif 8353901Smckusick 8453901Smckusick #ifdef news3400 8553901Smckusick #define MAXCTLR 8 8653901Smckusick #endif 8753901Smckusick 8853901Smckusick #ifdef news3800 8953901Smckusick #define MAXCTLR 16 9053901Smckusick #endif 9153901Smckusick 9253901Smckusick #define MAXSLAVE 8 9353901Smckusick 9453901Smckusick struct scsi scsi[MAXCTLR]; 9553901Smckusick struct sc_map scmap[MAXCTLR]; 9653901Smckusick struct sc_inq scinq[MAXCTLR]; 9753901Smckusick 9853901Smckusick #ifdef IPC_MRX 9953901Smckusick extern int port_scsi; /* UNIX port of SCSI */ 10053901Smckusick extern int iop_scsi[]; /* IOP port of SCSI process */ 10153901Smckusick #endif 10253901Smckusick 10353901Smckusick #ifdef CPU_DOUBLE 10453901Smckusick extern struct scintsw scintsw[]; 10553901Smckusick #endif 10653901Smckusick 10753901Smckusick /* 10853901Smckusick * Universal SCSI probe routine 10953901Smckusick * for mass storage controller. 11053901Smckusick */ 11153901Smckusick psdprobe(im) 11253901Smckusick register struct iop/**/_ctlr *im; 11353901Smckusick { 11453901Smckusick register int intr = im->im_intr; 11553901Smckusick struct scintsw *sci; 11653901Smckusick int ctlrintr; 11753901Smckusick int j; 11853901Smckusick char name[16]; 11953901Smckusick register struct sc_inq *inq = &scinq[intr]; 12053901Smckusick 12153901Smckusick #ifdef IPC_MRX 12253901Smckusick int scintr(); 12353901Smckusick 12453901Smckusick if (port_scsi == 0) { 12553901Smckusick port_scsi = port_create("@scsi", scintr, -1); 12653901Smckusick for(j = 0; j < MAXCTLR; j++) { 12753901Smckusick if(j == 7 || j == 15) 12853901Smckusick continue; 12953901Smckusick iop_scsi[j] = object_query(make_name(name, "scsiportXX", j)); 13053901Smckusick } 13153901Smckusick } 13253901Smckusick #endif /* IPC_MRX */ 13353901Smckusick sci = &scintsw[intr]; 13453901Smckusick if (sci->sci_inthandler) { 13553901Smckusick /* 13653901Smckusick * already probed. 13753901Smckusick */ 13853901Smckusick return (-1); 13953901Smckusick } 14053901Smckusick 14153901Smckusick /* 14253901Smckusick * probe device product ID 14353901Smckusick * & set driver interrupt handler 14453901Smckusick */ 14553901Smckusick if (probe_inq(im, inq) == 0) { 14653901Smckusick /* 14753901Smckusick * inquiry command terminate with bad status 14853901Smckusick * set 0x7f(Specified device is nonexistent) to devtype 14953901Smckusick */ 15053901Smckusick inq->sci_devtype = NOSUCHDEV; 15153901Smckusick } 15253901Smckusick return (inq->sci_devtype); 15353901Smckusick } 15453901Smckusick 15553901Smckusick set_inthandler(im, handler) 15653901Smckusick register struct iop/**/_ctlr *im; 15753901Smckusick int (*handler)(); 15853901Smckusick { 15953901Smckusick struct scintsw *sci; 16053901Smckusick 16153901Smckusick sci = &scintsw[im->im_intr]; 16253901Smckusick if (sci->sci_inthandler) 16353901Smckusick return (0); /* already probed. */ 16453901Smckusick 16553901Smckusick sci->sci_inthandler = handler; 16653901Smckusick sci->sci_ctlr = im->im_ctlr; 16753901Smckusick return (1); 16853901Smckusick } 16953901Smckusick 17053901Smckusick probe_inq(im, inq) 17153901Smckusick register struct iop/**/_ctlr *im; 17253901Smckusick register struct sc_inq *inq; 17353901Smckusick { 17453901Smckusick register int intr = im->im_intr; 17553901Smckusick register struct scsi *sc = &scsi[intr]; 17653901Smckusick register int retry = 0; 17753901Smckusick 17853901Smckusick bzero(inq, sizeof(struct sc_inq)); 17953901Smckusick 18053901Smckusick psdprobe_loop: 18153901Smckusick 18253901Smckusick scop_inquiry(intr, sc, 0, SCSI_INTDIS, sizeof(struct sc_inq), inq); 18353901Smckusick 18453901Smckusick if (sc->sc_istatus != INST_EP) { 18553901Smckusick /* 18653901Smckusick * probe fault. 18753901Smckusick */ 18853901Smckusick if (sc->sc_istatus == (INST_EP|INST_HE)) { 18953901Smckusick /* 19053901Smckusick * bus reset, retry 19153901Smckusick */ 19253901Smckusick goto psdprobe_loop; 19353901Smckusick } 19453901Smckusick return (0); 19553901Smckusick } 19653901Smckusick #ifndef NO_STATUS_BYTE_MASK 19753901Smckusick sc->sc_tstatus &= TGSTMASK; 19853901Smckusick #endif /* !NO_STATUS_BYTE_MASK */ 19953901Smckusick if (sc->sc_tstatus != TGST_GOOD) { 20053901Smckusick if (sc->sc_tstatus == TGST_CC) 20153901Smckusick scop_rsense(intr, sc, 0, SCSI_INTDIS, 18, 0); 20253901Smckusick if (retry++ < PROBE_MAXRETRY) { 20353901Smckusick DELAY(600000); /* XXX 1 sec */ 20453901Smckusick goto psdprobe_loop; 20553901Smckusick } 20653901Smckusick /* 20753901Smckusick * probe fault. 20853901Smckusick */ 20953901Smckusick return (0); 21053901Smckusick } 21153901Smckusick return (1); 21253901Smckusick } 21353901Smckusick 21453901Smckusick struct scsi * 21553901Smckusick get_scsi(intr) 21653901Smckusick int intr; 21753901Smckusick { 21853901Smckusick return (&scsi[intr]); 21953901Smckusick } 22053901Smckusick 22153901Smckusick struct sc_map * 22253901Smckusick get_sc_map(intr) 22353901Smckusick int intr; 22453901Smckusick { 22553901Smckusick return (&scmap[intr]); 22653901Smckusick } 22753901Smckusick 22853901Smckusick struct sc_inq * 22953901Smckusick get_sc_inq(intr) 23053901Smckusick int intr; 23153901Smckusick { 23253901Smckusick return (&scinq[intr]); 23353901Smckusick } 234