133519Sbostic /*
233519Sbostic * Copyright (c) 1988 Regents of the University of California.
333519Sbostic * All rights reserved.
433519Sbostic *
544546Sbostic * %sccs.include.redist.c%
633519Sbostic *
7*49100Sbostic * @(#)kdb.c 7.9 (Berkeley) 05/04/91
833519Sbostic */
933519Sbostic
1033519Sbostic /*
1133519Sbostic * KDB50/RAxx disk device driver
1233519Sbostic */
1345803Sbostic #include "../include/pte.h"
1433519Sbostic
1545803Sbostic #include "sys/param.h"
1645803Sbostic #include "sys/disklabel.h"
1733519Sbostic
1845803Sbostic #include "stand/saio.h"
1933519Sbostic #include "savax.h"
2033519Sbostic
2134984Sbostic /*
2234984Sbostic * N.B.: on KDB50, controller == adapter
2334984Sbostic * here we just use the controller number
2434984Sbostic */
2534984Sbostic
2634984Sbostic #define NKRA 8 /* max drive number */
2733519Sbostic #define SECTSIZ 512 /* sector size in bytes */
2833519Sbostic
2933519Sbostic /*
3034984Sbostic * Parameters for the communications area:
3134984Sbostic * command and response rings both one entry.
3233519Sbostic */
3333519Sbostic #define NRSP 1
3433519Sbostic #define NCMD 1
3533519Sbostic
3645803Sbostic #include "../bi/bireg.h"
3745803Sbostic #include "../bi/kdbreg.h"
3833519Sbostic #include "../vax/mscp.h"
3933519Sbostic
4033519Sbostic struct kdb {
4133519Sbostic struct kdbca kdb_ca;
4233519Sbostic struct mscp kdb_rsp;
4333519Sbostic struct mscp kdb_cmd;
4433519Sbostic } kdb;
4533519Sbostic
4633519Sbostic int kdbinit[MAXNKDB];
4734984Sbostic struct disklabel kralabel[MAXNKDB][NKRA];
4834984Sbostic u_long kramedia[MAXNKDB][NKRA];
4933519Sbostic char lbuf[SECTSIZ];
5033519Sbostic
kraopen(io)5133519Sbostic kraopen(io)
5233519Sbostic register struct iob *io;
5333519Sbostic {
5433519Sbostic register struct kdb_regs *kr;
5533519Sbostic register struct disklabel *lp;
5634984Sbostic register int ctlr, unit;
5734984Sbostic struct iob tio;
5833519Sbostic
5934984Sbostic if ((u_int)(ctlr = io->i_ctlr) >= nkdb)
6034984Sbostic return (EADAPT);
6134984Sbostic if ((u_int)(unit = io->i_unit) >= NKRA)
6234460Sbostic return (EUNIT);
6334984Sbostic kr = (struct kdb_regs *)kdbaddr[ctlr];
6434984Sbostic if (kdbinit[ctlr] == 0) {
6533519Sbostic kr->kdb_bi.bi_csr |= BICSR_NRST;
6633519Sbostic DELAY(10000); /* ??? */
6733519Sbostic /* clear any bus errors */
6833519Sbostic kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
6933519Sbostic while ((kr->kdb_sa & KDB_STEP1) == 0)
7034984Sbostic /* void */;
7133519Sbostic kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN;
7233519Sbostic kr->kdb_sw = KDB_ERR;
7333519Sbostic while ((kr->kdb_sa & KDB_STEP2) == 0)
7434984Sbostic /* void */;
7533519Sbostic kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0];
7633519Sbostic while ((kr->kdb_sa & KDB_STEP3) == 0)
7734984Sbostic /* void */;
7833519Sbostic kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16;
7933519Sbostic while ((kr->kdb_sa & KDB_STEP4) == 0)
8034984Sbostic /* void */;
8133519Sbostic kr->kdb_sw = KDB_GO;
8233519Sbostic kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref;
8333519Sbostic kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref;
8434984Sbostic if (kdbcmd(M_OP_SETCTLRC, io)) {
8534984Sbostic printf("kra: open error, SETCTLRC\n");
8634984Sbostic return (ENXIO);
8733519Sbostic }
8834984Sbostic kdbinit[ctlr] = 1;
8933519Sbostic }
9034984Sbostic lp = &kralabel[ctlr][unit];
9134984Sbostic if (kramedia[ctlr][unit] == 0) {
9234984Sbostic kdb.kdb_cmd.mscp_unit = unit;
9334984Sbostic if (kdbcmd(M_OP_ONLINE, io)) {
9434984Sbostic printf("kra: open error, ONLINE\n");
9534984Sbostic return (ENXIO);
9633519Sbostic }
9734984Sbostic kramedia[ctlr][unit] = kdb.kdb_rsp.mscp_onle.onle_mediaid;
9833519Sbostic tio = *io;
9933519Sbostic tio.i_bn = LABELSECTOR;
10033519Sbostic tio.i_ma = lbuf;
10133519Sbostic tio.i_cc = SECTSIZ;
10233519Sbostic tio.i_flgs |= F_RDDATA;
103*49100Sbostic if (krastrategy(&tio, F_READ) != SECTSIZ)
10434460Sbostic return (ERDLAB);
10533519Sbostic *lp = *(struct disklabel *)(lbuf + LABELOFFSET);
10634984Sbostic if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
10734460Sbostic #ifdef COMPAT_42
10833519Sbostic printf("kra%d: unlabeled\n", unit);
10933519Sbostic kramaptype(io, lp);
11033519Sbostic #else
11134460Sbostic return (EUNLAB);
11233519Sbostic #endif
11334984Sbostic }
11433519Sbostic }
11534984Sbostic if ((u_int)io->i_part >= lp->d_npartitions ||
11634460Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
11734460Sbostic return (EPART);
11833519Sbostic return (0);
11933519Sbostic }
12033519Sbostic
kdbcmd(op,io)12134984Sbostic kdbcmd(op, io)
12233519Sbostic int op;
12334984Sbostic struct iob *io;
12433519Sbostic {
12533519Sbostic register struct kdb *k = &kdb;
12633519Sbostic register struct mscp *mp;
12734984Sbostic register int i;
12833519Sbostic
12933519Sbostic k->kdb_cmd.mscp_opcode = op;
13033519Sbostic k->kdb_rsp.mscp_msglen = MSCP_MSGLEN;
13133519Sbostic k->kdb_cmd.mscp_msglen = MSCP_MSGLEN;
13233519Sbostic k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
13333519Sbostic k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT;
13434984Sbostic i = ((struct kdb_regs *)kdbaddr[io->i_ctlr])->kdb_ip;
13534984Sbostic #ifdef lint
13634984Sbostic i = i;
13734984Sbostic #endif
13833519Sbostic mp = &k->kdb_rsp;
13933519Sbostic for (;;) {
14033519Sbostic if (k->kdb_ca.ca_cmdint)
14133519Sbostic k->kdb_ca.ca_cmdint = 0;
14233519Sbostic if (k->kdb_ca.ca_rspint == 0)
14333519Sbostic continue;
14433519Sbostic k->kdb_ca.ca_rspint = 0;
14533519Sbostic if (mp->mscp_opcode == (op | M_OP_END))
14633519Sbostic break;
14733519Sbostic printf("unexpected rsp type %x op %x ignored\n",
14833519Sbostic MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
14934984Sbostic k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
15033519Sbostic }
15133519Sbostic if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS)
15233519Sbostic return (-1);
15333519Sbostic return (0);
15433519Sbostic }
15533519Sbostic
krastrategy(io,func)15633519Sbostic krastrategy(io, func)
15733519Sbostic register struct iob *io;
15834984Sbostic int func;
15933519Sbostic {
16033519Sbostic register struct mscp *mp;
16133519Sbostic
16233519Sbostic mp = &kdb.kdb_cmd;
16334984Sbostic mp->mscp_unit = io->i_unit;
16433519Sbostic mp->mscp_seq.seq_lbn = io->i_bn;
16533519Sbostic mp->mscp_seq.seq_bytecount = io->i_cc;
16633519Sbostic mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS;
167*49100Sbostic if (kdbcmd(func == F_READ ? M_OP_READ : M_OP_WRITE, io)) {
16833519Sbostic printf("kra: I/O error\n");
16933519Sbostic return (-1);
17033519Sbostic }
17133519Sbostic return (io->i_cc);
17233519Sbostic }
17333519Sbostic
17433519Sbostic #ifdef COMPAT_42
17533519Sbostic u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
17634984Sbostic #define kra70_off kra60_off
17733519Sbostic u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
17833519Sbostic u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 };
17934984Sbostic u_long kra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
18034984Sbostic
18134984Sbostic struct mediamap {
18234984Sbostic u_long id; /* media ID */
18334984Sbostic u_long *off; /* offsets */
18434984Sbostic } kra_map[] = {
18534984Sbostic { MSCP_MKDRIVE2('R', 'A', 60), kra60_off },
18634984Sbostic { MSCP_MKDRIVE2('R', 'A', 70), kra70_off },
18734984Sbostic { MSCP_MKDRIVE2('R', 'A', 80), kra80_off },
18834984Sbostic { MSCP_MKDRIVE2('R', 'A', 81), kra81_off },
18934984Sbostic { MSCP_MKDRIVE2('R', 'A', 82), kra82_off },
19034984Sbostic 0
19133519Sbostic };
19233519Sbostic
kramaptype(io,lp)19333519Sbostic kramaptype(io, lp)
19433519Sbostic register struct iob *io;
19533519Sbostic register struct disklabel *lp;
19633519Sbostic {
19733519Sbostic register struct partition *pp;
19834984Sbostic register u_long i;
19934984Sbostic register struct mediamap *map;
20033519Sbostic
20134984Sbostic i = MSCP_MEDIA_DRIVE(kramedia[io->i_ctlr][io->i_unit]);
20234984Sbostic for (map = kra_map; map->id != 0; map++) {
20334984Sbostic if (map->id == i) {
20434984Sbostic lp->d_npartitions = 8;
20534984Sbostic for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
20634984Sbostic pp->p_offset = map->off[i];
20734984Sbostic return;
20834984Sbostic }
20933519Sbostic }
21034984Sbostic printf("kra%d: media type 0x%x unsupported\n", io->i_unit, i);
21134984Sbostic lp->d_npartitions = 0;
21233519Sbostic }
21333519Sbostic #endif
214