1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kdb.c 7.9 (Berkeley) 05/04/91 8 */ 9 10 /* 11 * KDB50/RAxx disk device driver 12 */ 13 #include "../include/pte.h" 14 15 #include "sys/param.h" 16 #include "sys/disklabel.h" 17 18 #include "stand/saio.h" 19 #include "savax.h" 20 21 /* 22 * N.B.: on KDB50, controller == adapter 23 * here we just use the controller number 24 */ 25 26 #define NKRA 8 /* max drive number */ 27 #define SECTSIZ 512 /* sector size in bytes */ 28 29 /* 30 * Parameters for the communications area: 31 * command and response rings both one entry. 32 */ 33 #define NRSP 1 34 #define NCMD 1 35 36 #include "../bi/bireg.h" 37 #include "../bi/kdbreg.h" 38 #include "../vax/mscp.h" 39 40 struct kdb { 41 struct kdbca kdb_ca; 42 struct mscp kdb_rsp; 43 struct mscp kdb_cmd; 44 } kdb; 45 46 int kdbinit[MAXNKDB]; 47 struct disklabel kralabel[MAXNKDB][NKRA]; 48 u_long kramedia[MAXNKDB][NKRA]; 49 char lbuf[SECTSIZ]; 50 51 kraopen(io) 52 register struct iob *io; 53 { 54 register struct kdb_regs *kr; 55 register struct disklabel *lp; 56 register int ctlr, unit; 57 struct iob tio; 58 59 if ((u_int)(ctlr = io->i_ctlr) >= nkdb) 60 return (EADAPT); 61 if ((u_int)(unit = io->i_unit) >= NKRA) 62 return (EUNIT); 63 kr = (struct kdb_regs *)kdbaddr[ctlr]; 64 if (kdbinit[ctlr] == 0) { 65 kr->kdb_bi.bi_csr |= BICSR_NRST; 66 DELAY(10000); /* ??? */ 67 /* clear any bus errors */ 68 kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN); 69 while ((kr->kdb_sa & KDB_STEP1) == 0) 70 /* void */; 71 kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN; 72 kr->kdb_sw = KDB_ERR; 73 while ((kr->kdb_sa & KDB_STEP2) == 0) 74 /* void */; 75 kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0]; 76 while ((kr->kdb_sa & KDB_STEP3) == 0) 77 /* void */; 78 kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16; 79 while ((kr->kdb_sa & KDB_STEP4) == 0) 80 /* void */; 81 kr->kdb_sw = KDB_GO; 82 kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref; 83 kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref; 84 if (kdbcmd(M_OP_SETCTLRC, io)) { 85 printf("kra: open error, SETCTLRC\n"); 86 return (ENXIO); 87 } 88 kdbinit[ctlr] = 1; 89 } 90 lp = &kralabel[ctlr][unit]; 91 if (kramedia[ctlr][unit] == 0) { 92 kdb.kdb_cmd.mscp_unit = unit; 93 if (kdbcmd(M_OP_ONLINE, io)) { 94 printf("kra: open error, ONLINE\n"); 95 return (ENXIO); 96 } 97 kramedia[ctlr][unit] = kdb.kdb_rsp.mscp_onle.onle_mediaid; 98 tio = *io; 99 tio.i_bn = LABELSECTOR; 100 tio.i_ma = lbuf; 101 tio.i_cc = SECTSIZ; 102 tio.i_flgs |= F_RDDATA; 103 if (krastrategy(&tio, F_READ) != SECTSIZ) 104 return (ERDLAB); 105 *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 106 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 107 #ifdef COMPAT_42 108 printf("kra%d: unlabeled\n", unit); 109 kramaptype(io, lp); 110 #else 111 return (EUNLAB); 112 #endif 113 } 114 } 115 if ((u_int)io->i_part >= lp->d_npartitions || 116 (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 117 return (EPART); 118 return (0); 119 } 120 121 kdbcmd(op, io) 122 int op; 123 struct iob *io; 124 { 125 register struct kdb *k = &kdb; 126 register struct mscp *mp; 127 register int i; 128 129 k->kdb_cmd.mscp_opcode = op; 130 k->kdb_rsp.mscp_msglen = MSCP_MSGLEN; 131 k->kdb_cmd.mscp_msglen = MSCP_MSGLEN; 132 k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT; 133 k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT; 134 i = ((struct kdb_regs *)kdbaddr[io->i_ctlr])->kdb_ip; 135 #ifdef lint 136 i = i; 137 #endif 138 mp = &k->kdb_rsp; 139 for (;;) { 140 if (k->kdb_ca.ca_cmdint) 141 k->kdb_ca.ca_cmdint = 0; 142 if (k->kdb_ca.ca_rspint == 0) 143 continue; 144 k->kdb_ca.ca_rspint = 0; 145 if (mp->mscp_opcode == (op | M_OP_END)) 146 break; 147 printf("unexpected rsp type %x op %x ignored\n", 148 MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 149 k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT; 150 } 151 if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) 152 return (-1); 153 return (0); 154 } 155 156 krastrategy(io, func) 157 register struct iob *io; 158 int func; 159 { 160 register struct mscp *mp; 161 162 mp = &kdb.kdb_cmd; 163 mp->mscp_unit = io->i_unit; 164 mp->mscp_seq.seq_lbn = io->i_bn; 165 mp->mscp_seq.seq_bytecount = io->i_cc; 166 mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS; 167 if (kdbcmd(func == F_READ ? M_OP_READ : M_OP_WRITE, io)) { 168 printf("kra: I/O error\n"); 169 return (-1); 170 } 171 return (io->i_cc); 172 } 173 174 #ifdef COMPAT_42 175 u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 176 #define kra70_off kra60_off 177 u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 178 u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 }; 179 u_long kra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 }; 180 181 struct mediamap { 182 u_long id; /* media ID */ 183 u_long *off; /* offsets */ 184 } kra_map[] = { 185 { MSCP_MKDRIVE2('R', 'A', 60), kra60_off }, 186 { MSCP_MKDRIVE2('R', 'A', 70), kra70_off }, 187 { MSCP_MKDRIVE2('R', 'A', 80), kra80_off }, 188 { MSCP_MKDRIVE2('R', 'A', 81), kra81_off }, 189 { MSCP_MKDRIVE2('R', 'A', 82), kra82_off }, 190 0 191 }; 192 193 kramaptype(io, lp) 194 register struct iob *io; 195 register struct disklabel *lp; 196 { 197 register struct partition *pp; 198 register u_long i; 199 register struct mediamap *map; 200 201 i = MSCP_MEDIA_DRIVE(kramedia[io->i_ctlr][io->i_unit]); 202 for (map = kra_map; map->id != 0; map++) { 203 if (map->id == i) { 204 lp->d_npartitions = 8; 205 for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 206 pp->p_offset = map->off[i]; 207 return; 208 } 209 } 210 printf("kra%d: media type 0x%x unsupported\n", io->i_unit, i); 211 lp->d_npartitions = 0; 212 } 213 #endif 214