1*33519Sbostic /* 2*33519Sbostic * Copyright (c) 1988 Regents of the University of California. 3*33519Sbostic * All rights reserved. 4*33519Sbostic * 5*33519Sbostic * Redistribution and use in source and binary forms are permitted 6*33519Sbostic * provided that this notice is preserved and that due credit is given 7*33519Sbostic * to the University of California at Berkeley. The name of the University 8*33519Sbostic * may not be used to endorse or promote products derived from this 9*33519Sbostic * software without specific prior written permission. This software 10*33519Sbostic * is provided ``as is'' without express or implied warranty. 11*33519Sbostic * 12*33519Sbostic * @(#)kdb.c 7.1 (Berkeley) 02/22/88 13*33519Sbostic */ 14*33519Sbostic 15*33519Sbostic /* 16*33519Sbostic * KDB50/RAxx disk device driver 17*33519Sbostic */ 18*33519Sbostic #include "../machine/pte.h" 19*33519Sbostic 20*33519Sbostic #include "param.h" 21*33519Sbostic #include "inode.h" 22*33519Sbostic #include "fs.h" 23*33519Sbostic #include "disklabel.h" 24*33519Sbostic 25*33519Sbostic #include "saio.h" 26*33519Sbostic #include "savax.h" 27*33519Sbostic 28*33519Sbostic #define NKRA 8 /* max unit number on ctlr */ 29*33519Sbostic #define SECTSIZ 512 /* sector size in bytes */ 30*33519Sbostic 31*33519Sbostic /* 32*33519Sbostic * Parameters for the communications area 33*33519Sbostic */ 34*33519Sbostic #define NRSP 1 35*33519Sbostic #define NCMD 1 36*33519Sbostic 37*33519Sbostic #include "../vax/bireg.h" 38*33519Sbostic #include "../vax/kdbreg.h" 39*33519Sbostic #include "../vax/mscp.h" 40*33519Sbostic 41*33519Sbostic struct kdb { 42*33519Sbostic struct kdbca kdb_ca; 43*33519Sbostic struct mscp kdb_rsp; 44*33519Sbostic struct mscp kdb_cmd; 45*33519Sbostic } kdb; 46*33519Sbostic 47*33519Sbostic int kdbinit[MAXNKDB]; 48*33519Sbostic char kratype[MAXNKDB * NKRA]; 49*33519Sbostic struct disklabel kralabel[MAXNUBA * NKRA]; 50*33519Sbostic char lbuf[SECTSIZ]; 51*33519Sbostic 52*33519Sbostic kraopen(io) 53*33519Sbostic register struct iob *io; 54*33519Sbostic { 55*33519Sbostic register struct mscp *mp; 56*33519Sbostic register struct kdb_regs *kr; 57*33519Sbostic register struct disklabel *lp; 58*33519Sbostic register int i, unit; 59*33519Sbostic daddr_t off; 60*33519Sbostic 61*33519Sbostic i = io->i_unit >> 3; 62*33519Sbostic if (i >= nkdb) { 63*33519Sbostic printf("nonexistent device"); 64*33519Sbostic return (ENXIO); 65*33519Sbostic } 66*33519Sbostic kr = (struct kdb_regs *)kdbaddr[i]; 67*33519Sbostic if (kdbinit[i] == 0) { 68*33519Sbostic kr->kdb_bi.bi_csr |= BICSR_NRST; 69*33519Sbostic DELAY(10000); /* ??? */ 70*33519Sbostic /* clear any bus errors */ 71*33519Sbostic kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN); 72*33519Sbostic while ((kr->kdb_sa & KDB_STEP1) == 0) 73*33519Sbostic ; 74*33519Sbostic kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN; 75*33519Sbostic kr->kdb_sw = KDB_ERR; 76*33519Sbostic while ((kr->kdb_sa & KDB_STEP2) == 0) 77*33519Sbostic ; 78*33519Sbostic kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0]; 79*33519Sbostic while ((kr->kdb_sa & KDB_STEP3) == 0) 80*33519Sbostic ; 81*33519Sbostic kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16; 82*33519Sbostic while ((kr->kdb_sa & KDB_STEP4) == 0) 83*33519Sbostic ; 84*33519Sbostic kr->kdb_sw = KDB_GO; 85*33519Sbostic kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref; 86*33519Sbostic kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref; 87*33519Sbostic if (kdbcmd(kr, M_OP_SETCTLRC)) { 88*33519Sbostic printf("open error, SETCTLRC"); 89*33519Sbostic return (EIO); 90*33519Sbostic } 91*33519Sbostic kdbinit[i] = 1; 92*33519Sbostic } 93*33519Sbostic unit = io->i_unit; 94*33519Sbostic lp = &kralabel[unit]; 95*33519Sbostic if (kratype[unit] == 0) { 96*33519Sbostic struct iob tio; 97*33519Sbostic 98*33519Sbostic kdb.kdb_cmd.mscp_unit = UNITTODRIVE(unit); 99*33519Sbostic if (kdbcmd(kr, M_OP_ONLINE)) { 100*33519Sbostic printf("open error, ONLINE"); 101*33519Sbostic return (EIO); 102*33519Sbostic } 103*33519Sbostic kratype[unit] = kdb.kdb_rsp.mscp_onle.onle_drivetype; 104*33519Sbostic tio = *io; 105*33519Sbostic tio.i_bn = LABELSECTOR; 106*33519Sbostic tio.i_ma = lbuf; 107*33519Sbostic tio.i_cc = SECTSIZ; 108*33519Sbostic tio.i_flgs |= F_RDDATA; 109*33519Sbostic if (krastrategy(&tio, READ) != SECTSIZ) { 110*33519Sbostic printf("can't read disk label\n"); 111*33519Sbostic return (EIO); 112*33519Sbostic } 113*33519Sbostic *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 114*33519Sbostic if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 115*33519Sbostic printf("kra%d: unlabeled\n", unit); 116*33519Sbostic #ifdef COMPAT_42 117*33519Sbostic kramaptype(io, lp); 118*33519Sbostic #else 119*33519Sbostic return (ENXIO); 120*33519Sbostic #endif 121*33519Sbostic } 122*33519Sbostic } 123*33519Sbostic if ((unsigned)io->i_boff >= lp->d_npartitions || 124*33519Sbostic (io->i_boff = lp->d_partitions[io->i_boff].p_offset) == -1) { 125*33519Sbostic printf("kra: bad partition"); 126*33519Sbostic return (EUNIT); 127*33519Sbostic } 128*33519Sbostic return (0); 129*33519Sbostic } 130*33519Sbostic 131*33519Sbostic kdbcmd(kr, op) 132*33519Sbostic struct kdb_regs *kr; 133*33519Sbostic int op; 134*33519Sbostic { 135*33519Sbostic register struct kdb *k = &kdb; 136*33519Sbostic register struct mscp *mp; 137*33519Sbostic int i; 138*33519Sbostic 139*33519Sbostic k->kdb_cmd.mscp_opcode = op; 140*33519Sbostic k->kdb_rsp.mscp_msglen = MSCP_MSGLEN; 141*33519Sbostic k->kdb_cmd.mscp_msglen = MSCP_MSGLEN; 142*33519Sbostic k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT; 143*33519Sbostic k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT; 144*33519Sbostic i = kr->kdb_ip; 145*33519Sbostic mp = &k->kdb_rsp; 146*33519Sbostic for (;;) { 147*33519Sbostic if (k->kdb_ca.ca_cmdint) 148*33519Sbostic k->kdb_ca.ca_cmdint = 0; 149*33519Sbostic if (k->kdb_ca.ca_rspint == 0) 150*33519Sbostic continue; 151*33519Sbostic k->kdb_ca.ca_rspint = 0; 152*33519Sbostic if (mp->mscp_opcode == (op | M_OP_END)) 153*33519Sbostic break; 154*33519Sbostic printf("unexpected rsp type %x op %x ignored\n", 155*33519Sbostic MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 156*33519Sbostic } 157*33519Sbostic if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) 158*33519Sbostic return (-1); 159*33519Sbostic return (0); 160*33519Sbostic } 161*33519Sbostic 162*33519Sbostic krastrategy(io, func) 163*33519Sbostic register struct iob *io; 164*33519Sbostic { 165*33519Sbostic register struct mscp *mp; 166*33519Sbostic 167*33519Sbostic mp = &kdb.kdb_cmd; 168*33519Sbostic mp->mscp_unit = io->i_unit & 7; 169*33519Sbostic mp->mscp_seq.seq_lbn = io->i_bn; 170*33519Sbostic mp->mscp_seq.seq_bytecount = io->i_cc; 171*33519Sbostic mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS; 172*33519Sbostic if (kdbcmd((struct kdb_regs *)kdbaddr[io->i_unit >> 3], 173*33519Sbostic func == READ ? M_OP_READ : M_OP_WRITE)) { 174*33519Sbostic printf("kra: I/O error\n"); 175*33519Sbostic return (-1); 176*33519Sbostic } 177*33519Sbostic return (io->i_cc); 178*33519Sbostic } 179*33519Sbostic 180*33519Sbostic /*ARGSUSED*/ 181*33519Sbostic kraioctl(io, cmd, arg) 182*33519Sbostic struct iob *io; 183*33519Sbostic int cmd; 184*33519Sbostic caddr_t arg; 185*33519Sbostic { 186*33519Sbostic 187*33519Sbostic return (ECMD); 188*33519Sbostic } 189*33519Sbostic 190*33519Sbostic #ifdef COMPAT_42 191*33519Sbostic u_long kra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 192*33519Sbostic u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 193*33519Sbostic u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 194*33519Sbostic u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 }; 195*33519Sbostic u_long *kra_off[] = { 196*33519Sbostic 0, 197*33519Sbostic kra80_off, /* 1 = ra80 */ 198*33519Sbostic kra25_off, /* 2 = rc25-r */ 199*33519Sbostic kra25_off, /* 3 = rc25-r */ 200*33519Sbostic kra60_off, /* 4 = ra60 */ 201*33519Sbostic kra81_off, /* 5 = ra81 */ 202*33519Sbostic }; 203*33519Sbostic #define NOFFS (sizeof(kra_off) / sizeof(kra_off[0])) 204*33519Sbostic 205*33519Sbostic kramaptype(io, lp) 206*33519Sbostic register struct iob *io; 207*33519Sbostic register struct disklabel *lp; 208*33519Sbostic { 209*33519Sbostic register struct partition *pp; 210*33519Sbostic register u_int i; 211*33519Sbostic register u_long *off; 212*33519Sbostic 213*33519Sbostic if ((i = kratype[io->i_unit]) >= NOFFS || (off = kra_off[i]) == 0) { 214*33519Sbostic printf("kra%d: type %d unsupported\n", io->i_unit, i); 215*33519Sbostic lp->d_npartitions = 0; 216*33519Sbostic return; 217*33519Sbostic } 218*33519Sbostic lp->d_npartitions = 8; 219*33519Sbostic for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 220*33519Sbostic pp->p_offset = *off++; 221*33519Sbostic } 222*33519Sbostic #endif 223