xref: /csrg-svn/sys/vax/stand/kdb.c (revision 34870)
133519Sbostic /*
233519Sbostic  * Copyright (c) 1988 Regents of the University of California.
333519Sbostic  * All rights reserved.
433519Sbostic  *
533519Sbostic  * Redistribution and use in source and binary forms are permitted
6*34870Sbostic  * provided that the above copyright notice and this paragraph are
7*34870Sbostic  * duplicated in all such forms and that any documentation,
8*34870Sbostic  * advertising materials, and other materials related to such
9*34870Sbostic  * distribution and use acknowledge that the software was developed
10*34870Sbostic  * by the University of California, Berkeley.  The name of the
11*34870Sbostic  * University may not be used to endorse or promote products derived
12*34870Sbostic  * from this software without specific prior written permission.
13*34870Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34870Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34870Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1633519Sbostic  *
17*34870Sbostic  *	@(#)kdb.c	7.3 (Berkeley) 06/29/88
1833519Sbostic  */
1933519Sbostic 
2033519Sbostic /*
2133519Sbostic  * KDB50/RAxx disk device driver
2233519Sbostic  */
2333519Sbostic #include "../machine/pte.h"
2433519Sbostic 
2533519Sbostic #include "param.h"
2633519Sbostic #include "inode.h"
2733519Sbostic #include "fs.h"
2833519Sbostic #include "disklabel.h"
2933519Sbostic 
3033519Sbostic #include "saio.h"
3133519Sbostic #include "savax.h"
3233519Sbostic 
3333519Sbostic #define	NKRA		8	/* max unit number on ctlr */
3433519Sbostic #define	SECTSIZ		512	/* sector size in bytes */
3533519Sbostic 
3633519Sbostic /*
3733519Sbostic  * Parameters for the communications area
3833519Sbostic  */
3933519Sbostic #define	NRSP	1
4033519Sbostic #define	NCMD	1
4133519Sbostic 
4234460Sbostic #include "../vaxbi/bireg.h"
4334460Sbostic #include "../vaxbi/kdbreg.h"
4433519Sbostic #include "../vax/mscp.h"
4533519Sbostic 
4633519Sbostic struct kdb {
4733519Sbostic 	struct kdbca	kdb_ca;
4833519Sbostic 	struct mscp	kdb_rsp;
4933519Sbostic 	struct mscp	kdb_cmd;
5033519Sbostic } kdb;
5133519Sbostic 
5233519Sbostic int	kdbinit[MAXNKDB];
5333519Sbostic char	kratype[MAXNKDB * NKRA];
5433519Sbostic struct	disklabel kralabel[MAXNUBA * NKRA];
5533519Sbostic char	lbuf[SECTSIZ];
5633519Sbostic 
5733519Sbostic kraopen(io)
5833519Sbostic 	register struct iob *io;
5933519Sbostic {
6033519Sbostic 	register struct mscp *mp;
6133519Sbostic 	register struct kdb_regs *kr;
6233519Sbostic 	register struct disklabel *lp;
6333519Sbostic 	register int i, unit;
6433519Sbostic 	daddr_t off;
6533519Sbostic 
6634460Sbostic 	if ((i = io->i_unit) >= nkdb)
6734460Sbostic 		return (EUNIT);
6833519Sbostic 	kr = (struct kdb_regs *)kdbaddr[i];
6933519Sbostic 	if (kdbinit[i] == 0) {
7033519Sbostic 		kr->kdb_bi.bi_csr |= BICSR_NRST;
7133519Sbostic 		DELAY(10000);	/* ??? */
7233519Sbostic 		/* clear any bus errors */
7333519Sbostic 		kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
7433519Sbostic 		while ((kr->kdb_sa & KDB_STEP1) == 0)
7533519Sbostic 			;
7633519Sbostic 		kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN;
7733519Sbostic 		kr->kdb_sw = KDB_ERR;
7833519Sbostic 		while ((kr->kdb_sa & KDB_STEP2) == 0)
7933519Sbostic 			;
8033519Sbostic 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0];
8133519Sbostic 		while ((kr->kdb_sa & KDB_STEP3) == 0)
8233519Sbostic 			;
8333519Sbostic 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16;
8433519Sbostic 		while ((kr->kdb_sa & KDB_STEP4) == 0)
8533519Sbostic 			;
8633519Sbostic 		kr->kdb_sw = KDB_GO;
8733519Sbostic 		kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref;
8833519Sbostic 		kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref;
8933519Sbostic 		if (kdbcmd(kr, M_OP_SETCTLRC)) {
9033519Sbostic 			printf("open error, SETCTLRC");
9133519Sbostic 			return (EIO);
9233519Sbostic 		}
9333519Sbostic 		kdbinit[i] = 1;
9433519Sbostic 	}
9533519Sbostic 	unit = io->i_unit;
9633519Sbostic 	lp = &kralabel[unit];
9733519Sbostic 	if (kratype[unit] == 0) {
9833519Sbostic 		struct iob tio;
9933519Sbostic 
10033519Sbostic 		kdb.kdb_cmd.mscp_unit = UNITTODRIVE(unit);
10133519Sbostic 		if (kdbcmd(kr, M_OP_ONLINE)) {
10233519Sbostic 			printf("open error, ONLINE");
10333519Sbostic 			return (EIO);
10433519Sbostic 		}
10533519Sbostic 		kratype[unit] = kdb.kdb_rsp.mscp_onle.onle_drivetype;
10633519Sbostic 		tio = *io;
10733519Sbostic 		tio.i_bn = LABELSECTOR;
10833519Sbostic 		tio.i_ma = lbuf;
10933519Sbostic 		tio.i_cc = SECTSIZ;
11033519Sbostic 		tio.i_flgs |= F_RDDATA;
11134460Sbostic 		if (krastrategy(&tio, READ) != SECTSIZ)
11234460Sbostic 			return (ERDLAB);
11333519Sbostic 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
11434460Sbostic 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC)
11534460Sbostic #ifdef COMPAT_42
11634460Sbostic 		{
11733519Sbostic 			printf("kra%d: unlabeled\n", unit);
11833519Sbostic 			kramaptype(io, lp);
11934460Sbostic 		}
12033519Sbostic #else
12134460Sbostic 			return (EUNLAB);
12233519Sbostic #endif
12333519Sbostic 	}
12434460Sbostic 	if ((unsigned)io->i_part >= lp->d_npartitions ||
12534460Sbostic 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
12634460Sbostic 		return (EPART);
12733519Sbostic 	return (0);
12833519Sbostic }
12933519Sbostic 
13033519Sbostic kdbcmd(kr, op)
13133519Sbostic 	struct kdb_regs *kr;
13233519Sbostic 	int op;
13333519Sbostic {
13433519Sbostic 	register struct kdb *k = &kdb;
13533519Sbostic 	register struct mscp *mp;
13633519Sbostic 	int i;
13733519Sbostic 
13833519Sbostic 	k->kdb_cmd.mscp_opcode = op;
13933519Sbostic 	k->kdb_rsp.mscp_msglen = MSCP_MSGLEN;
14033519Sbostic 	k->kdb_cmd.mscp_msglen = MSCP_MSGLEN;
14133519Sbostic 	k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
14233519Sbostic 	k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT;
14333519Sbostic 	i = kr->kdb_ip;
14433519Sbostic 	mp = &k->kdb_rsp;
14533519Sbostic 	for (;;) {
14633519Sbostic 		if (k->kdb_ca.ca_cmdint)
14733519Sbostic 			k->kdb_ca.ca_cmdint = 0;
14833519Sbostic 		if (k->kdb_ca.ca_rspint == 0)
14933519Sbostic 			continue;
15033519Sbostic 		k->kdb_ca.ca_rspint = 0;
15133519Sbostic 		if (mp->mscp_opcode == (op | M_OP_END))
15233519Sbostic 			break;
15333519Sbostic 		printf("unexpected rsp type %x op %x ignored\n",
15433519Sbostic 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
15533519Sbostic 	}
15633519Sbostic 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS)
15733519Sbostic 		return (-1);
15833519Sbostic 	return (0);
15933519Sbostic }
16033519Sbostic 
16133519Sbostic krastrategy(io, func)
16233519Sbostic 	register struct iob *io;
16333519Sbostic {
16433519Sbostic 	register struct mscp *mp;
16533519Sbostic 
16633519Sbostic 	mp = &kdb.kdb_cmd;
16733519Sbostic 	mp->mscp_unit = io->i_unit & 7;
16833519Sbostic 	mp->mscp_seq.seq_lbn = io->i_bn;
16933519Sbostic 	mp->mscp_seq.seq_bytecount = io->i_cc;
17033519Sbostic 	mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS;
17133519Sbostic 	if (kdbcmd((struct kdb_regs *)kdbaddr[io->i_unit >> 3],
17233519Sbostic 		    func == READ ? M_OP_READ : M_OP_WRITE)) {
17333519Sbostic 		printf("kra: I/O error\n");
17433519Sbostic 		return (-1);
17533519Sbostic 	}
17633519Sbostic 	return (io->i_cc);
17733519Sbostic }
17833519Sbostic 
17933519Sbostic #ifdef COMPAT_42
18033519Sbostic u_long kra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
18133519Sbostic u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
18233519Sbostic u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
18333519Sbostic u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 };
18433519Sbostic u_long *kra_off[] = {
18533519Sbostic 	0,
18633519Sbostic 	kra80_off,		/* 1 = ra80 */
18733519Sbostic 	kra25_off,		/* 2 = rc25-r */
18833519Sbostic 	kra25_off,		/* 3 = rc25-r */
18933519Sbostic 	kra60_off,		/* 4 = ra60 */
19033519Sbostic 	kra81_off,		/* 5 = ra81 */
19133519Sbostic };
19233519Sbostic #define	NOFFS (sizeof(kra_off) / sizeof(kra_off[0]))
19333519Sbostic 
19433519Sbostic kramaptype(io, lp)
19533519Sbostic 	register struct iob *io;
19633519Sbostic 	register struct disklabel *lp;
19733519Sbostic {
19833519Sbostic 	register struct partition *pp;
19933519Sbostic 	register u_int i;
20033519Sbostic 	register u_long *off;
20133519Sbostic 
20233519Sbostic 	if ((i = kratype[io->i_unit]) >= NOFFS || (off = kra_off[i]) == 0) {
20333519Sbostic 		printf("kra%d: type %d unsupported\n", io->i_unit, i);
20433519Sbostic 		lp->d_npartitions = 0;
20533519Sbostic 		return;
20633519Sbostic 	}
20733519Sbostic 	lp->d_npartitions = 8;
20833519Sbostic 	for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
20933519Sbostic 		pp->p_offset = *off++;
21033519Sbostic }
21133519Sbostic #endif
212