153901Smckusick /*
2*63307Sbostic * Copyright (c) 1992, 1993
3*63307Sbostic * The Regents of the University of California. 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*63307Sbostic * @(#)psd.c 8.1 (Berkeley) 06/11/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 */
psdprobe(im)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
set_inthandler(im,handler)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
probe_inq(im,inq)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;
18058617Sutashiro #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 *
get_scsi(intr)19753901Smckusick get_scsi(intr)
19853901Smckusick int intr;
19953901Smckusick {
20053901Smckusick return (&scsi[intr]);
20153901Smckusick }
20253901Smckusick
20353901Smckusick struct sc_map *
get_sc_map(intr)20453901Smckusick get_sc_map(intr)
20553901Smckusick int intr;
20653901Smckusick {
20753901Smckusick return (&scmap[intr]);
20853901Smckusick }
20953901Smckusick
21053901Smckusick struct sc_inq *
get_sc_inq(intr)21153901Smckusick get_sc_inq(intr)
21253901Smckusick int intr;
21353901Smckusick {
21453901Smckusick return (&scinq[intr]);
21553901Smckusick }
216