123247Smckusick /* 2*35050Skarels * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 323247Smckusick * All rights reserved. The Berkeley software License Agreement 423247Smckusick * specifies the terms and conditions for redistribution. 523247Smckusick * 6*35050Skarels * @(#)uda.c 7.9 (Berkeley) 07/09/88 723247Smckusick */ 85153Ssam 95153Ssam /* 105153Ssam * UDA50/RAxx disk device driver 115153Ssam */ 125153Ssam 1332613Sbostic #include "param.h" 1432613Sbostic #include "inode.h" 15*35050Skarels #include "buf.h" 1632613Sbostic #include "fs.h" 1732613Sbostic #include "disklabel.h" 189186Ssam 19*35050Skarels #include "../vax/pte.h" 20*35050Skarels 215153Ssam #include "saio.h" 225153Ssam #include "savax.h" 235153Ssam 245153Ssam /* 2532613Sbostic * Unused, but needed in udareg.h 265153Ssam */ 2732613Sbostic #define NRSP 1 2832613Sbostic #define NCMD 1 295153Ssam 3033408Skarels #include "../vaxuba/udareg.h" 319186Ssam #include "../vaxuba/ubareg.h" 32*35050Skarels #include "../vaxuba/ubavar.h" 3333408Skarels #include "../vax/mscp.h" 345153Ssam 35*35050Skarels #define NRA 8 /* max. unit number on controller */ 36*35050Skarels #define SECTSIZ 512 /* sector size in bytes */ 37*35050Skarels 3833543Sbostic #define MAXCTLR 1 /* all addresses must be specified */ 3933543Sbostic u_short udastd[MAXCTLR] = { 0772150 }; 405153Ssam 4133543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR]; 425153Ssam 4332613Sbostic struct uda1 { 4432613Sbostic struct uda1ca uda1_ca; /* communications area */ 4532613Sbostic struct mscp uda1_rsp; /* response packet */ 4632613Sbostic struct mscp uda1_cmd; /* command packet */ 4732613Sbostic } uda1; 485153Ssam 4933543Sbostic /* Unibus address of uda structure */ 5033543Sbostic struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR]; 5133543Sbostic struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA]; 52*35050Skarels static u_long ramedia[MAXNUBA][MAXCTLR][NRA]; 5330547Skarels char lbuf[SECTSIZ]; 545153Ssam 5511111Ssam raopen(io) 565153Ssam register struct iob *io; 575153Ssam { 58*35050Skarels register struct disklabel *lp; 5930547Skarels register struct udadevice *addr; 60*35050Skarels register struct uda1 *ubaaddr; 6133764Sbostic register int uba, unit; 6233543Sbostic static int udainit[MAXNUBA][MAXCTLR]; 6333764Sbostic struct iob tio; 645153Ssam 65*35050Skarels if ((u_int)(uba = io->i_adapt) >= nuba) 66*35050Skarels return (EADAPT); 6733543Sbostic if ((u_int)io->i_ctlr >= MAXCTLR) 6833543Sbostic return (ECTLR); 69*35050Skarels if ((u_int)(unit = io->i_unit) >= NRA) 70*35050Skarels return (EUNIT); 7133543Sbostic addr = udaddr[uba][io->i_ctlr] = 7233543Sbostic (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]); 7333764Sbostic if (badaddr((char *)addr, sizeof(short))) 7430547Skarels return (ENXIO); 75*35050Skarels if ((ubaaddr = ud_ubaddr[uba][io->i_ctlr]) == 0) { 7633764Sbostic tio = *io; 7733764Sbostic tio.i_ma = (caddr_t)&uda1; 7833764Sbostic tio.i_cc = sizeof(uda1); 79*35050Skarels ud_ubaddr[uba][io->i_ctlr] = ubaaddr = 80*35050Skarels (struct uda1 *)ubasetup(&tio, 2); 815153Ssam } 8233543Sbostic if (udainit[uba][io->i_ctlr] == 0) { 8330547Skarels addr->udaip = 0; 8433764Sbostic while ((addr->udasa & UDA_STEP1) == 0); 8530547Skarels addr->udasa = UDA_ERR; 8633764Sbostic while ((addr->udasa & UDA_STEP2) == 0); 87*35050Skarels addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc; 8833764Sbostic while ((addr->udasa & UDA_STEP3) == 0); 89*35050Skarels addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc >> 16; 9033764Sbostic while ((addr->udasa & UDA_STEP4) == 0); 9130547Skarels addr->udasa = UDA_GO; 92*35050Skarels uda1.uda1_ca.ca_rspdsc = (long)&ubaaddr->uda1_rsp.mscp_cmdref; 93*35050Skarels uda1.uda1_ca.ca_cmddsc = (long)&ubaaddr->uda1_cmd.mscp_cmdref; 9432613Sbostic /* uda1.uda1_cmd.mscp_cntflgs = 0; */ 9533408Skarels if (udcmd(M_OP_SETCTLRC, io)) { 9632613Sbostic printf("ra: open error, SETCTLRC\n"); 9733543Sbostic return (ENXIO); 9817231Smckusick } 9933543Sbostic udainit[uba][io->i_ctlr] = 1; 10027075Skarels } 10133543Sbostic lp = &ralabel[uba][io->i_ctlr][unit]; 102*35050Skarels if (ramedia[uba][io->i_ctlr][unit] == 0) { 10333543Sbostic uda1.uda1_cmd.mscp_unit = unit; 10433408Skarels if (udcmd(M_OP_ONLINE, io)) { 10532613Sbostic printf("ra: open error, ONLINE\n"); 10633543Sbostic return (ENXIO); 10717231Smckusick } 108*35050Skarels ramedia[uba][io->i_ctlr][unit] = 109*35050Skarels uda1.uda1_rsp.mscp_onle.onle_mediaid; 11030547Skarels tio = *io; 11130547Skarels tio.i_bn = LABELSECTOR; 11230547Skarels tio.i_ma = lbuf; 11330547Skarels tio.i_cc = SECTSIZ; 11430547Skarels tio.i_flgs |= F_RDDATA; 11533764Sbostic if (rastrategy(&tio, READ) != SECTSIZ) 11633764Sbostic return (ERDLAB); 11733408Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 118*35050Skarels if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 11933764Sbostic #ifdef COMPAT_42 12030547Skarels printf("ra%d: unlabeled\n", unit); 12130547Skarels ramaptype(io, lp); 12230547Skarels #else 12333764Sbostic return (EUNLAB); 12430547Skarels #endif 125*35050Skarels } 1265153Ssam } 12733543Sbostic if ((u_int)io->i_part >= lp->d_npartitions || 12833543Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 12933543Sbostic return (EPART); 13030547Skarels return (0); 1315153Ssam } 1325153Ssam 13333408Skarels int 13430547Skarels udcmd(op, io) 1355153Ssam int op; 13630547Skarels register struct iob *io; 1375153Ssam { 13833408Skarels register struct uda1 *u = &uda1; 13932613Sbostic register struct mscp *mp; 14033764Sbostic register int i; 1415153Ssam 14233408Skarels u->uda1_cmd.mscp_opcode = op; 14333408Skarels u->uda1_cmd.mscp_msglen = MSCP_MSGLEN; 14433408Skarels u->uda1_rsp.mscp_msglen = MSCP_MSGLEN; 14533408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 14633408Skarels u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 14733764Sbostic i = udaddr[io->i_adapt][io->i_ctlr]->udaip; /* start uda polling */ 148*35050Skarels #ifdef lint 149*35050Skarels i = i; 150*35050Skarels #endif 15133408Skarels mp = &u->uda1_rsp; 1525153Ssam for (;;) { 15333408Skarels if (u->uda1_ca.ca_cmdint) 15433408Skarels u->uda1_ca.ca_cmdint = 0; 15533408Skarels if (u->uda1_ca.ca_rspint == 0) 15632613Sbostic continue; 15733408Skarels u->uda1_ca.ca_rspint = 0; 15832613Sbostic if (mp->mscp_opcode == (op | M_OP_END)) 1595153Ssam break; 16033408Skarels printf("unexpected rsp type %x op %x ignored\n", 16133408Skarels MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 16233408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 1635153Ssam } 16432613Sbostic if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS) 16533408Skarels return (-1); 16633408Skarels return (0); 1675153Ssam } 1685153Ssam 16911111Ssam rastrategy(io, func) 1705153Ssam register struct iob *io; 171*35050Skarels int func; 1725153Ssam { 1735153Ssam register struct mscp *mp; 174*35050Skarels register int ubinfo; 1755153Ssam 1765153Ssam ubinfo = ubasetup(io, 1); 17732613Sbostic mp = &uda1.uda1_cmd; 17833543Sbostic mp->mscp_unit = io->i_unit; 17932613Sbostic mp->mscp_seq.seq_lbn = io->i_bn; 18032613Sbostic mp->mscp_seq.seq_bytecount = io->i_cc; 181*35050Skarels mp->mscp_seq.seq_buffer = UBAI_ADDR(ubinfo) | (UBAI_BDP(ubinfo) << 24); 18233408Skarels if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) { 1835153Ssam printf("ra: I/O error\n"); 1845153Ssam ubafree(io, ubinfo); 185*35050Skarels return (-1); 1865153Ssam } 1875153Ssam ubafree(io, ubinfo); 188*35050Skarels return (io->i_cc); 1895153Ssam } 19010024Ssam 19130547Skarels #ifdef COMPAT_42 192*35050Skarels u_long rc25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 19332613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 19432613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 }; 19532613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 }; 19630547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 197*35050Skarels #define ra70_off ra60_off 19830547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 19930547Skarels #ifndef UCBRA 20030547Skarels #ifdef RA_COMPAT 20130547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; 20230547Skarels #else 20330547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; 20430547Skarels #endif 20530547Skarels #else 20630547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; 20730547Skarels #endif 208*35050Skarels u_long ra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 }; 20930547Skarels 210*35050Skarels struct mediamap { 211*35050Skarels u_long id; /* media ID */ 212*35050Skarels u_long *off; /* offsets */ 213*35050Skarels } ra_map[] = { 214*35050Skarels { MSCP_MKDRIVE2('R', 'A', 60), ra60_off }, 215*35050Skarels { MSCP_MKDRIVE2('R', 'A', 70), ra70_off }, 216*35050Skarels { MSCP_MKDRIVE2('R', 'A', 80), ra80_off }, 217*35050Skarels { MSCP_MKDRIVE2('R', 'A', 81), ra81_off }, 218*35050Skarels { MSCP_MKDRIVE2('R', 'A', 82), ra82_off }, 219*35050Skarels { MSCP_MKDRIVE2('R', 'C', 25), rc25_off }, 220*35050Skarels { MSCP_MKDRIVE3('R', 'C', 'F', 25), rc25_off }, 221*35050Skarels { MSCP_MKDRIVE2('R', 'D', 52), rd52_off }, 222*35050Skarels { MSCP_MKDRIVE2('R', 'D', 53), rd53_off }, 223*35050Skarels { MSCP_MKDRIVE2('R', 'X', 50), rx50_off }, 224*35050Skarels 0 22532613Sbostic }; 22632613Sbostic 22730547Skarels ramaptype(io, lp) 22830547Skarels register struct iob *io; 22930547Skarels register struct disklabel *lp; 23030547Skarels { 23130547Skarels register struct partition *pp; 232*35050Skarels register u_long i; 233*35050Skarels register struct mediamap *map; 23430547Skarels 235*35050Skarels i = MSCP_MEDIA_DRIVE(ramedia[io->i_adapt][io->i_ctlr][io->i_unit]); 236*35050Skarels for (map = ra_map; map->id != 0; map++) { 237*35050Skarels if (map->id == i) { 238*35050Skarels lp->d_npartitions = 8; 239*35050Skarels for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 240*35050Skarels pp->p_offset = map->off[i]; 241*35050Skarels return; 242*35050Skarels } 24330547Skarels } 244*35050Skarels printf("ra%d: media type 0x%x unsupported\n", io->i_unit, i); 245*35050Skarels lp->d_npartitions = 0; 24630547Skarels } 24730547Skarels #endif 248