xref: /csrg-svn/sys/vax/stand/kdb.c (revision 34984)
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
634870Sbostic  * provided that the above copyright notice and this paragraph are
734870Sbostic  * duplicated in all such forms and that any documentation,
834870Sbostic  * advertising materials, and other materials related to such
934870Sbostic  * distribution and use acknowledge that the software was developed
1034870Sbostic  * by the University of California, Berkeley.  The name of the
1134870Sbostic  * University may not be used to endorse or promote products derived
1234870Sbostic  * from this software without specific prior written permission.
1334870Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434870Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534870Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1633519Sbostic  *
17*34984Sbostic  *	@(#)kdb.c	7.4 (Berkeley) 07/08/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 
33*34984Sbostic /*
34*34984Sbostic  * N.B.: on KDB50, controller == adapter
35*34984Sbostic  * here we just use the controller number
36*34984Sbostic  */
37*34984Sbostic 
38*34984Sbostic #define	NKRA		8	/* max drive number */
3933519Sbostic #define	SECTSIZ		512	/* sector size in bytes */
4033519Sbostic 
4133519Sbostic /*
42*34984Sbostic  * Parameters for the communications area:
43*34984Sbostic  * command and response rings both one entry.
4433519Sbostic  */
4533519Sbostic #define	NRSP	1
4633519Sbostic #define	NCMD	1
4733519Sbostic 
4834460Sbostic #include "../vaxbi/bireg.h"
4934460Sbostic #include "../vaxbi/kdbreg.h"
5033519Sbostic #include "../vax/mscp.h"
5133519Sbostic 
5233519Sbostic struct kdb {
5333519Sbostic 	struct kdbca	kdb_ca;
5433519Sbostic 	struct mscp	kdb_rsp;
5533519Sbostic 	struct mscp	kdb_cmd;
5633519Sbostic } kdb;
5733519Sbostic 
5833519Sbostic int	kdbinit[MAXNKDB];
59*34984Sbostic struct	disklabel kralabel[MAXNKDB][NKRA];
60*34984Sbostic u_long	kramedia[MAXNKDB][NKRA];
6133519Sbostic char	lbuf[SECTSIZ];
6233519Sbostic 
6333519Sbostic kraopen(io)
6433519Sbostic 	register struct iob *io;
6533519Sbostic {
6633519Sbostic 	register struct kdb_regs *kr;
6733519Sbostic 	register struct disklabel *lp;
68*34984Sbostic 	register int ctlr, unit;
69*34984Sbostic 	struct iob tio;
7033519Sbostic 
71*34984Sbostic 	if ((u_int)(ctlr = io->i_ctlr) >= nkdb)
72*34984Sbostic 		return (EADAPT);
73*34984Sbostic 	if ((u_int)(unit = io->i_unit) >= NKRA)
7434460Sbostic 		return (EUNIT);
75*34984Sbostic 	kr = (struct kdb_regs *)kdbaddr[ctlr];
76*34984Sbostic 	if (kdbinit[ctlr] == 0) {
7733519Sbostic 		kr->kdb_bi.bi_csr |= BICSR_NRST;
7833519Sbostic 		DELAY(10000);	/* ??? */
7933519Sbostic 		/* clear any bus errors */
8033519Sbostic 		kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
8133519Sbostic 		while ((kr->kdb_sa & KDB_STEP1) == 0)
82*34984Sbostic 			/* void */;
8333519Sbostic 		kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN;
8433519Sbostic 		kr->kdb_sw = KDB_ERR;
8533519Sbostic 		while ((kr->kdb_sa & KDB_STEP2) == 0)
86*34984Sbostic 			/* void */;
8733519Sbostic 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0];
8833519Sbostic 		while ((kr->kdb_sa & KDB_STEP3) == 0)
89*34984Sbostic 			/* void */;
9033519Sbostic 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16;
9133519Sbostic 		while ((kr->kdb_sa & KDB_STEP4) == 0)
92*34984Sbostic 			/* void */;
9333519Sbostic 		kr->kdb_sw = KDB_GO;
9433519Sbostic 		kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref;
9533519Sbostic 		kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref;
96*34984Sbostic 		if (kdbcmd(M_OP_SETCTLRC, io)) {
97*34984Sbostic 			printf("kra: open error, SETCTLRC\n");
98*34984Sbostic 			return (ENXIO);
9933519Sbostic 		}
100*34984Sbostic 		kdbinit[ctlr] = 1;
10133519Sbostic 	}
102*34984Sbostic 	lp = &kralabel[ctlr][unit];
103*34984Sbostic 	if (kramedia[ctlr][unit] == 0) {
104*34984Sbostic 		kdb.kdb_cmd.mscp_unit = unit;
105*34984Sbostic 		if (kdbcmd(M_OP_ONLINE, io)) {
106*34984Sbostic 			printf("kra: open error, ONLINE\n");
107*34984Sbostic 			return (ENXIO);
10833519Sbostic 		}
109*34984Sbostic 		kramedia[ctlr][unit] = kdb.kdb_rsp.mscp_onle.onle_mediaid;
11033519Sbostic 		tio = *io;
11133519Sbostic 		tio.i_bn = LABELSECTOR;
11233519Sbostic 		tio.i_ma = lbuf;
11333519Sbostic 		tio.i_cc = SECTSIZ;
11433519Sbostic 		tio.i_flgs |= F_RDDATA;
11534460Sbostic 		if (krastrategy(&tio, READ) != SECTSIZ)
11634460Sbostic 			return (ERDLAB);
11733519Sbostic 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
118*34984Sbostic 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
11934460Sbostic #ifdef COMPAT_42
12033519Sbostic 			printf("kra%d: unlabeled\n", unit);
12133519Sbostic 			kramaptype(io, lp);
12233519Sbostic #else
12334460Sbostic 			return (EUNLAB);
12433519Sbostic #endif
125*34984Sbostic 		}
12633519Sbostic 	}
127*34984Sbostic 	if ((u_int)io->i_part >= lp->d_npartitions ||
12834460Sbostic 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
12934460Sbostic 		return (EPART);
13033519Sbostic 	return (0);
13133519Sbostic }
13233519Sbostic 
133*34984Sbostic kdbcmd(op, io)
13433519Sbostic 	int op;
135*34984Sbostic 	struct iob *io;
13633519Sbostic {
13733519Sbostic 	register struct kdb *k = &kdb;
13833519Sbostic 	register struct mscp *mp;
139*34984Sbostic 	register int i;
14033519Sbostic 
14133519Sbostic 	k->kdb_cmd.mscp_opcode = op;
14233519Sbostic 	k->kdb_rsp.mscp_msglen = MSCP_MSGLEN;
14333519Sbostic 	k->kdb_cmd.mscp_msglen = MSCP_MSGLEN;
14433519Sbostic 	k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
14533519Sbostic 	k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT;
146*34984Sbostic 	i = ((struct kdb_regs *)kdbaddr[io->i_ctlr])->kdb_ip;
147*34984Sbostic #ifdef lint
148*34984Sbostic 	i = i;
149*34984Sbostic #endif
15033519Sbostic 	mp = &k->kdb_rsp;
15133519Sbostic 	for (;;) {
15233519Sbostic 		if (k->kdb_ca.ca_cmdint)
15333519Sbostic 			k->kdb_ca.ca_cmdint = 0;
15433519Sbostic 		if (k->kdb_ca.ca_rspint == 0)
15533519Sbostic 			continue;
15633519Sbostic 		k->kdb_ca.ca_rspint = 0;
15733519Sbostic 		if (mp->mscp_opcode == (op | M_OP_END))
15833519Sbostic 			break;
15933519Sbostic 		printf("unexpected rsp type %x op %x ignored\n",
16033519Sbostic 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
161*34984Sbostic 		k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
16233519Sbostic 	}
16333519Sbostic 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS)
16433519Sbostic 		return (-1);
16533519Sbostic 	return (0);
16633519Sbostic }
16733519Sbostic 
16833519Sbostic krastrategy(io, func)
16933519Sbostic 	register struct iob *io;
170*34984Sbostic 	int func;
17133519Sbostic {
17233519Sbostic 	register struct mscp *mp;
17333519Sbostic 
17433519Sbostic 	mp = &kdb.kdb_cmd;
175*34984Sbostic 	mp->mscp_unit = io->i_unit;
17633519Sbostic 	mp->mscp_seq.seq_lbn = io->i_bn;
17733519Sbostic 	mp->mscp_seq.seq_bytecount = io->i_cc;
17833519Sbostic 	mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS;
179*34984Sbostic 	if (kdbcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) {
18033519Sbostic 		printf("kra: I/O error\n");
18133519Sbostic 		return (-1);
18233519Sbostic 	}
18333519Sbostic 	return (io->i_cc);
18433519Sbostic }
18533519Sbostic 
18633519Sbostic #ifdef COMPAT_42
18733519Sbostic u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
188*34984Sbostic #define kra70_off kra60_off
18933519Sbostic u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
19033519Sbostic u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 };
191*34984Sbostic u_long kra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
192*34984Sbostic 
193*34984Sbostic struct mediamap {
194*34984Sbostic 	u_long	id;		/* media ID */
195*34984Sbostic 	u_long	*off;		/* offsets */
196*34984Sbostic } kra_map[] = {
197*34984Sbostic 	{ MSCP_MKDRIVE2('R', 'A', 60),		kra60_off },
198*34984Sbostic 	{ MSCP_MKDRIVE2('R', 'A', 70),		kra70_off },
199*34984Sbostic 	{ MSCP_MKDRIVE2('R', 'A', 80),		kra80_off },
200*34984Sbostic 	{ MSCP_MKDRIVE2('R', 'A', 81),		kra81_off },
201*34984Sbostic 	{ MSCP_MKDRIVE2('R', 'A', 82),		kra82_off },
202*34984Sbostic 	0
20333519Sbostic };
20433519Sbostic 
20533519Sbostic kramaptype(io, lp)
20633519Sbostic 	register struct iob *io;
20733519Sbostic 	register struct disklabel *lp;
20833519Sbostic {
20933519Sbostic 	register struct partition *pp;
210*34984Sbostic 	register u_long i;
211*34984Sbostic 	register struct mediamap *map;
21233519Sbostic 
213*34984Sbostic 	i = MSCP_MEDIA_DRIVE(kramedia[io->i_ctlr][io->i_unit]);
214*34984Sbostic 	for (map = kra_map; map->id != 0; map++) {
215*34984Sbostic 		if (map->id == i) {
216*34984Sbostic 			lp->d_npartitions = 8;
217*34984Sbostic 			for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
218*34984Sbostic 				pp->p_offset = map->off[i];
219*34984Sbostic 			return;
220*34984Sbostic 		}
22133519Sbostic 	}
222*34984Sbostic 	printf("kra%d: media type 0x%x unsupported\n", io->i_unit, i);
223*34984Sbostic 	lp->d_npartitions = 0;
22433519Sbostic }
22533519Sbostic #endif
226