133519Sbostic /* 233519Sbostic * Copyright (c) 1988 Regents of the University of California. 333519Sbostic * All rights reserved. 433519Sbostic * 5*44546Sbostic * %sccs.include.redist.c% 633519Sbostic * 7*44546Sbostic * @(#)kdb.c 7.7 (Berkeley) 06/28/90 833519Sbostic */ 933519Sbostic 1033519Sbostic /* 1133519Sbostic * KDB50/RAxx disk device driver 1233519Sbostic */ 1337510Smckusick #include "machine/pte.h" 1433519Sbostic 1533519Sbostic #include "param.h" 1633519Sbostic #include "disklabel.h" 1733519Sbostic 1833519Sbostic #include "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 3634460Sbostic #include "../vaxbi/bireg.h" 3734460Sbostic #include "../vaxbi/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 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; 10334460Sbostic if (krastrategy(&tio, 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 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 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; 16734984Sbostic if (kdbcmd(func == 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 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