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 6*34870Sbostic * provided that the above copyright notice and this paragraph are 7*34870Sbostic * duplicated in all such forms and that any documentation, 8*34870Sbostic * advertising materials, and other materials related to such 9*34870Sbostic * distribution and use acknowledge that the software was developed 10*34870Sbostic * by the University of California, Berkeley. The name of the 11*34870Sbostic * University may not be used to endorse or promote products derived 12*34870Sbostic * from this software without specific prior written permission. 13*34870Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34870Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34870Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1633519Sbostic * 17*34870Sbostic * @(#)kdb.c 7.3 (Berkeley) 06/29/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 3333519Sbostic #define NKRA 8 /* max unit number on ctlr */ 3433519Sbostic #define SECTSIZ 512 /* sector size in bytes */ 3533519Sbostic 3633519Sbostic /* 3733519Sbostic * Parameters for the communications area 3833519Sbostic */ 3933519Sbostic #define NRSP 1 4033519Sbostic #define NCMD 1 4133519Sbostic 4234460Sbostic #include "../vaxbi/bireg.h" 4334460Sbostic #include "../vaxbi/kdbreg.h" 4433519Sbostic #include "../vax/mscp.h" 4533519Sbostic 4633519Sbostic struct kdb { 4733519Sbostic struct kdbca kdb_ca; 4833519Sbostic struct mscp kdb_rsp; 4933519Sbostic struct mscp kdb_cmd; 5033519Sbostic } kdb; 5133519Sbostic 5233519Sbostic int kdbinit[MAXNKDB]; 5333519Sbostic char kratype[MAXNKDB * NKRA]; 5433519Sbostic struct disklabel kralabel[MAXNUBA * NKRA]; 5533519Sbostic char lbuf[SECTSIZ]; 5633519Sbostic 5733519Sbostic kraopen(io) 5833519Sbostic register struct iob *io; 5933519Sbostic { 6033519Sbostic register struct mscp *mp; 6133519Sbostic register struct kdb_regs *kr; 6233519Sbostic register struct disklabel *lp; 6333519Sbostic register int i, unit; 6433519Sbostic daddr_t off; 6533519Sbostic 6634460Sbostic if ((i = io->i_unit) >= nkdb) 6734460Sbostic return (EUNIT); 6833519Sbostic kr = (struct kdb_regs *)kdbaddr[i]; 6933519Sbostic if (kdbinit[i] == 0) { 7033519Sbostic kr->kdb_bi.bi_csr |= BICSR_NRST; 7133519Sbostic DELAY(10000); /* ??? */ 7233519Sbostic /* clear any bus errors */ 7333519Sbostic kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN); 7433519Sbostic while ((kr->kdb_sa & KDB_STEP1) == 0) 7533519Sbostic ; 7633519Sbostic kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN; 7733519Sbostic kr->kdb_sw = KDB_ERR; 7833519Sbostic while ((kr->kdb_sa & KDB_STEP2) == 0) 7933519Sbostic ; 8033519Sbostic kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0]; 8133519Sbostic while ((kr->kdb_sa & KDB_STEP3) == 0) 8233519Sbostic ; 8333519Sbostic kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16; 8433519Sbostic while ((kr->kdb_sa & KDB_STEP4) == 0) 8533519Sbostic ; 8633519Sbostic kr->kdb_sw = KDB_GO; 8733519Sbostic kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref; 8833519Sbostic kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref; 8933519Sbostic if (kdbcmd(kr, M_OP_SETCTLRC)) { 9033519Sbostic printf("open error, SETCTLRC"); 9133519Sbostic return (EIO); 9233519Sbostic } 9333519Sbostic kdbinit[i] = 1; 9433519Sbostic } 9533519Sbostic unit = io->i_unit; 9633519Sbostic lp = &kralabel[unit]; 9733519Sbostic if (kratype[unit] == 0) { 9833519Sbostic struct iob tio; 9933519Sbostic 10033519Sbostic kdb.kdb_cmd.mscp_unit = UNITTODRIVE(unit); 10133519Sbostic if (kdbcmd(kr, M_OP_ONLINE)) { 10233519Sbostic printf("open error, ONLINE"); 10333519Sbostic return (EIO); 10433519Sbostic } 10533519Sbostic kratype[unit] = kdb.kdb_rsp.mscp_onle.onle_drivetype; 10633519Sbostic tio = *io; 10733519Sbostic tio.i_bn = LABELSECTOR; 10833519Sbostic tio.i_ma = lbuf; 10933519Sbostic tio.i_cc = SECTSIZ; 11033519Sbostic tio.i_flgs |= F_RDDATA; 11134460Sbostic if (krastrategy(&tio, READ) != SECTSIZ) 11234460Sbostic return (ERDLAB); 11333519Sbostic *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 11434460Sbostic if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) 11534460Sbostic #ifdef COMPAT_42 11634460Sbostic { 11733519Sbostic printf("kra%d: unlabeled\n", unit); 11833519Sbostic kramaptype(io, lp); 11934460Sbostic } 12033519Sbostic #else 12134460Sbostic return (EUNLAB); 12233519Sbostic #endif 12333519Sbostic } 12434460Sbostic if ((unsigned)io->i_part >= lp->d_npartitions || 12534460Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 12634460Sbostic return (EPART); 12733519Sbostic return (0); 12833519Sbostic } 12933519Sbostic 13033519Sbostic kdbcmd(kr, op) 13133519Sbostic struct kdb_regs *kr; 13233519Sbostic int op; 13333519Sbostic { 13433519Sbostic register struct kdb *k = &kdb; 13533519Sbostic register struct mscp *mp; 13633519Sbostic int i; 13733519Sbostic 13833519Sbostic k->kdb_cmd.mscp_opcode = op; 13933519Sbostic k->kdb_rsp.mscp_msglen = MSCP_MSGLEN; 14033519Sbostic k->kdb_cmd.mscp_msglen = MSCP_MSGLEN; 14133519Sbostic k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT; 14233519Sbostic k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT; 14333519Sbostic i = kr->kdb_ip; 14433519Sbostic mp = &k->kdb_rsp; 14533519Sbostic for (;;) { 14633519Sbostic if (k->kdb_ca.ca_cmdint) 14733519Sbostic k->kdb_ca.ca_cmdint = 0; 14833519Sbostic if (k->kdb_ca.ca_rspint == 0) 14933519Sbostic continue; 15033519Sbostic k->kdb_ca.ca_rspint = 0; 15133519Sbostic if (mp->mscp_opcode == (op | M_OP_END)) 15233519Sbostic break; 15333519Sbostic printf("unexpected rsp type %x op %x ignored\n", 15433519Sbostic MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 15533519Sbostic } 15633519Sbostic if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) 15733519Sbostic return (-1); 15833519Sbostic return (0); 15933519Sbostic } 16033519Sbostic 16133519Sbostic krastrategy(io, func) 16233519Sbostic register struct iob *io; 16333519Sbostic { 16433519Sbostic register struct mscp *mp; 16533519Sbostic 16633519Sbostic mp = &kdb.kdb_cmd; 16733519Sbostic mp->mscp_unit = io->i_unit & 7; 16833519Sbostic mp->mscp_seq.seq_lbn = io->i_bn; 16933519Sbostic mp->mscp_seq.seq_bytecount = io->i_cc; 17033519Sbostic mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS; 17133519Sbostic if (kdbcmd((struct kdb_regs *)kdbaddr[io->i_unit >> 3], 17233519Sbostic func == READ ? M_OP_READ : M_OP_WRITE)) { 17333519Sbostic printf("kra: I/O error\n"); 17433519Sbostic return (-1); 17533519Sbostic } 17633519Sbostic return (io->i_cc); 17733519Sbostic } 17833519Sbostic 17933519Sbostic #ifdef COMPAT_42 18033519Sbostic u_long kra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 18133519Sbostic u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 18233519Sbostic u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 18333519Sbostic u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 }; 18433519Sbostic u_long *kra_off[] = { 18533519Sbostic 0, 18633519Sbostic kra80_off, /* 1 = ra80 */ 18733519Sbostic kra25_off, /* 2 = rc25-r */ 18833519Sbostic kra25_off, /* 3 = rc25-r */ 18933519Sbostic kra60_off, /* 4 = ra60 */ 19033519Sbostic kra81_off, /* 5 = ra81 */ 19133519Sbostic }; 19233519Sbostic #define NOFFS (sizeof(kra_off) / sizeof(kra_off[0])) 19333519Sbostic 19433519Sbostic kramaptype(io, lp) 19533519Sbostic register struct iob *io; 19633519Sbostic register struct disklabel *lp; 19733519Sbostic { 19833519Sbostic register struct partition *pp; 19933519Sbostic register u_int i; 20033519Sbostic register u_long *off; 20133519Sbostic 20233519Sbostic if ((i = kratype[io->i_unit]) >= NOFFS || (off = kra_off[i]) == 0) { 20333519Sbostic printf("kra%d: type %d unsupported\n", io->i_unit, i); 20433519Sbostic lp->d_npartitions = 0; 20533519Sbostic return; 20633519Sbostic } 20733519Sbostic lp->d_npartitions = 8; 20833519Sbostic for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 20933519Sbostic pp->p_offset = *off++; 21033519Sbostic } 21133519Sbostic #endif 212