123247Smckusick /* 229315Smckusick * Copyright (c) 1982, 1986 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*33764Sbostic * @(#)uda.c 7.8 (Berkeley) 03/22/88 723247Smckusick */ 85153Ssam 95153Ssam /* 105153Ssam * UDA50/RAxx disk device driver 115153Ssam */ 129806Ssam #include "../machine/pte.h" 135153Ssam 1432613Sbostic #include "param.h" 1532613Sbostic #include "inode.h" 1632613Sbostic #include "fs.h" 1732613Sbostic #include "disklabel.h" 189186Ssam 195153Ssam #include "saio.h" 205153Ssam #include "savax.h" 215153Ssam 2232613Sbostic #define NRA 8 /* max. unit number on controller */ 2330547Skarels #define SECTSIZ 512 /* sector size in bytes */ 2432613Sbostic 255153Ssam /* 2632613Sbostic * Unused, but needed in udareg.h 275153Ssam */ 2832613Sbostic #define NRSP 1 2932613Sbostic #define NCMD 1 305153Ssam 3133408Skarels #include "../vaxuba/udareg.h" 329186Ssam #include "../vaxuba/ubareg.h" 3333408Skarels #include "../vax/mscp.h" 345153Ssam 3533543Sbostic #define MAXCTLR 1 /* all addresses must be specified */ 3633543Sbostic u_short udastd[MAXCTLR] = { 0772150 }; 375153Ssam 3833543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR]; 395153Ssam 4032613Sbostic struct uda1 { 4132613Sbostic struct uda1ca uda1_ca; /* communications area */ 4232613Sbostic struct mscp uda1_rsp; /* response packet */ 4332613Sbostic struct mscp uda1_cmd; /* command packet */ 4432613Sbostic } uda1; 455153Ssam 4633543Sbostic /* Unibus address of uda structure */ 4733543Sbostic struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR]; 4833543Sbostic struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA]; 4933543Sbostic static u_int ratype[MAXNUBA][MAXCTLR][NRA]; 5030547Skarels char lbuf[SECTSIZ]; 515153Ssam 5211111Ssam raopen(io) 535153Ssam register struct iob *io; 545153Ssam { 5532613Sbostic register struct disklabel *lp, *dlp; 5630547Skarels register struct udadevice *addr; 5732613Sbostic register struct uda1 *ubaddr; 58*33764Sbostic register int uba, unit; 5933543Sbostic static int udainit[MAXNUBA][MAXCTLR]; 60*33764Sbostic struct iob tio; 615153Ssam 6233543Sbostic if ((u_int)io->i_ctlr >= MAXCTLR) 6333543Sbostic return (ECTLR); 6430547Skarels unit = io->i_unit; 6533543Sbostic uba = io->i_adapt; 6633543Sbostic addr = udaddr[uba][io->i_ctlr] = 6733543Sbostic (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]); 68*33764Sbostic if (badaddr((char *)addr, sizeof(short))) 6930547Skarels return (ENXIO); 7033543Sbostic if (ud_ubaddr[uba][io->i_ctlr] == 0) { 71*33764Sbostic tio = *io; 72*33764Sbostic tio.i_ma = (caddr_t)&uda1; 73*33764Sbostic tio.i_cc = sizeof(uda1); 74*33764Sbostic ud_ubaddr[uba][io->i_ctlr] = (struct uda1 *)ubasetup(&tio, 2); 755153Ssam } 7633543Sbostic ubaddr = ud_ubaddr[uba][io->i_ctlr]; 7733543Sbostic if (udainit[uba][io->i_ctlr] == 0) { 7830547Skarels addr->udaip = 0; 79*33764Sbostic while ((addr->udasa & UDA_STEP1) == 0); 8030547Skarels addr->udasa = UDA_ERR; 81*33764Sbostic while ((addr->udasa & UDA_STEP2) == 0); 8232613Sbostic addr->udasa = (short)&ubaddr->uda1_ca.ca_rspdsc; 83*33764Sbostic while ((addr->udasa & UDA_STEP3) == 0); 8430547Skarels addr->udasa = 8532613Sbostic (short)(((int)&ubaddr->uda1_ca.ca_rspdsc) >> 16); 86*33764Sbostic while ((addr->udasa & UDA_STEP4) == 0); 8730547Skarels addr->udasa = UDA_GO; 8832613Sbostic uda1.uda1_ca.ca_rspdsc = (long)&ubaddr->uda1_rsp.mscp_cmdref; 8932613Sbostic uda1.uda1_ca.ca_cmddsc = (long)&ubaddr->uda1_cmd.mscp_cmdref; 9032613Sbostic /* uda1.uda1_cmd.mscp_cntflgs = 0; */ 9133408Skarels if (udcmd(M_OP_SETCTLRC, io)) { 9232613Sbostic printf("ra: open error, SETCTLRC\n"); 9333543Sbostic return (ENXIO); 9417231Smckusick } 9533543Sbostic udainit[uba][io->i_ctlr] = 1; 9627075Skarels } 9733543Sbostic lp = &ralabel[uba][io->i_ctlr][unit]; 9833543Sbostic if (ratype[uba][io->i_ctlr][unit] == 0) { 9933543Sbostic uda1.uda1_cmd.mscp_unit = unit; 10033408Skarels if (udcmd(M_OP_ONLINE, io)) { 10132613Sbostic printf("ra: open error, ONLINE\n"); 10233543Sbostic return (ENXIO); 10317231Smckusick } 10433543Sbostic ratype[uba][io->i_ctlr][unit] = 10533543Sbostic uda1.uda1_rsp.mscp_onle.onle_drivetype; 10630547Skarels tio = *io; 10730547Skarels tio.i_bn = LABELSECTOR; 10830547Skarels tio.i_ma = lbuf; 10930547Skarels tio.i_cc = SECTSIZ; 11030547Skarels tio.i_flgs |= F_RDDATA; 111*33764Sbostic if (rastrategy(&tio, READ) != SECTSIZ) 112*33764Sbostic return (ERDLAB); 11333408Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 114*33764Sbostic if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) 115*33764Sbostic #ifdef COMPAT_42 116*33764Sbostic { 11730547Skarels printf("ra%d: unlabeled\n", unit); 11830547Skarels ramaptype(io, lp); 119*33764Sbostic } 12030547Skarels #else 121*33764Sbostic return (EUNLAB); 12230547Skarels #endif 1235153Ssam } 12433543Sbostic if ((u_int)io->i_part >= lp->d_npartitions || 12533543Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 12633543Sbostic return (EPART); 12730547Skarels return (0); 1285153Ssam } 1295153Ssam 13033408Skarels int 13130547Skarels udcmd(op, io) 1325153Ssam int op; 13330547Skarels register struct iob *io; 1345153Ssam { 13533408Skarels register struct uda1 *u = &uda1; 13632613Sbostic register struct mscp *mp; 137*33764Sbostic register int i; 1385153Ssam 13933408Skarels u->uda1_cmd.mscp_opcode = op; 14033408Skarels u->uda1_cmd.mscp_msglen = MSCP_MSGLEN; 14133408Skarels u->uda1_rsp.mscp_msglen = MSCP_MSGLEN; 14233408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 14333408Skarels u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 144*33764Sbostic i = udaddr[io->i_adapt][io->i_ctlr]->udaip; /* start uda polling */ 14533408Skarels mp = &u->uda1_rsp; 1465153Ssam for (;;) { 14733408Skarels if (u->uda1_ca.ca_cmdint) 14833408Skarels u->uda1_ca.ca_cmdint = 0; 14933408Skarels if (u->uda1_ca.ca_rspint == 0) 15032613Sbostic continue; 15133408Skarels u->uda1_ca.ca_rspint = 0; 15232613Sbostic if (mp->mscp_opcode == (op | M_OP_END)) 1535153Ssam break; 15433408Skarels printf("unexpected rsp type %x op %x ignored\n", 15533408Skarels MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 15633408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 1575153Ssam } 15832613Sbostic if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS) 15933408Skarels return (-1); 16033408Skarels return (0); 1615153Ssam } 1625153Ssam 16311111Ssam rastrategy(io, func) 1645153Ssam register struct iob *io; 1655153Ssam { 1665153Ssam register struct mscp *mp; 1675153Ssam int ubinfo; 1685153Ssam 1695153Ssam ubinfo = ubasetup(io, 1); 17032613Sbostic mp = &uda1.uda1_cmd; 17133543Sbostic mp->mscp_unit = io->i_unit; 17232613Sbostic mp->mscp_seq.seq_lbn = io->i_bn; 17332613Sbostic mp->mscp_seq.seq_bytecount = io->i_cc; 17432613Sbostic mp->mscp_seq.seq_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 17533408Skarels if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) { 1765153Ssam printf("ra: I/O error\n"); 1775153Ssam ubafree(io, ubinfo); 1785153Ssam return(-1); 1795153Ssam } 1805153Ssam ubafree(io, ubinfo); 1815153Ssam return(io->i_cc); 1825153Ssam } 18310024Ssam 18430547Skarels #ifdef COMPAT_42 18530547Skarels u_long ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 18632613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 18732613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 }; 18832613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 }; 18930547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 19030547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 19130547Skarels #ifndef UCBRA 19230547Skarels #ifdef RA_COMPAT 19330547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; 19430547Skarels #else 19530547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; 19630547Skarels #endif 19730547Skarels #else 19830547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; 19930547Skarels #endif 20030547Skarels 20132613Sbostic u_long *ra_off[] = { 20232613Sbostic 0, /* 0 = unused */ 20332613Sbostic ra80_off, /* 1 = ra80 */ 20432613Sbostic ra25_off, /* 2 = rc25 removable */ 20532613Sbostic ra25_off, /* 3 = rc25 fixed */ 20632613Sbostic ra60_off, /* 4 = ra60 */ 20732613Sbostic ra81_off, /* 5 = ra81 */ 20832613Sbostic 0, /* 6 = ? */ 20932613Sbostic rx50_off, /* 7 = rx50 */ 21032613Sbostic rd52_off, /* 8 = rd52 */ 21132613Sbostic rd53_off, /* 9 = rd53 */ 21232613Sbostic }; 21332613Sbostic 21433408Skarels #define NOFFS (sizeof(ra_off)/sizeof(ra_off[0])) 21532613Sbostic 21630547Skarels ramaptype(io, lp) 21730547Skarels register struct iob *io; 21830547Skarels register struct disklabel *lp; 21930547Skarels { 22030547Skarels register struct partition *pp; 221*33764Sbostic register u_long *off; 22233408Skarels register u_int i; 22330547Skarels 22433543Sbostic if ((i = ratype[io->i_adapt][io->i_ctlr][io->i_unit]) >= NOFFS || 22533543Sbostic (off = ra_off[i]) == 0) { 22632613Sbostic printf("ra%d: ra type %d unsupported\n", io->i_unit, i); 22730547Skarels lp->d_npartitions = 0; 22830547Skarels return; 22930547Skarels } 23030547Skarels lp->d_npartitions = 8; 23132613Sbostic for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 23230547Skarels pp->p_offset = *off++; 23330547Skarels } 23430547Skarels #endif 235