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*33543Sbostic * @(#)uda.c 7.7 (Berkeley) 02/23/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 35*33543Sbostic #define MAXCTLR 1 /* all addresses must be specified */ 36*33543Sbostic u_short udastd[MAXCTLR] = { 0772150 }; 375153Ssam 385153Ssam struct iob cudbuf; 395153Ssam 40*33543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR]; 415153Ssam 4232613Sbostic struct uda1 { 4332613Sbostic struct uda1ca uda1_ca; /* communications area */ 4432613Sbostic struct mscp uda1_rsp; /* response packet */ 4532613Sbostic struct mscp uda1_cmd; /* command packet */ 4632613Sbostic } uda1; 475153Ssam 48*33543Sbostic /* Unibus address of uda structure */ 49*33543Sbostic struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR]; 50*33543Sbostic struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA]; 51*33543Sbostic static u_int ratype[MAXNUBA][MAXCTLR][NRA]; 5230547Skarels char lbuf[SECTSIZ]; 535153Ssam 5411111Ssam raopen(io) 555153Ssam register struct iob *io; 565153Ssam { 575153Ssam register struct mscp *mp; 5832613Sbostic register struct disklabel *lp, *dlp; 5930547Skarels register struct udadevice *addr; 6032613Sbostic register struct uda1 *ubaddr; 6130547Skarels register unit; 62*33543Sbostic static int udainit[MAXNUBA][MAXCTLR]; 6330547Skarels int uba; 645153Ssam 65*33543Sbostic if ((u_int)io->i_ctlr >= MAXCTLR) 66*33543Sbostic return (ECTLR); 6730547Skarels unit = io->i_unit; 68*33543Sbostic uba = io->i_adapt; 69*33543Sbostic addr = udaddr[uba][io->i_ctlr] = 70*33543Sbostic (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]); 7130547Skarels if (badaddr((char *)addr, sizeof(short))) { 72*33543Sbostic printf("ra: nonexistent device\n"); 7330547Skarels return (ENXIO); 7430547Skarels } 75*33543Sbostic if (ud_ubaddr[uba][io->i_ctlr] == 0) { 7617231Smckusick /* 7730547Skarels * Initialize cudbuf.i_unit so that controllers 7817231Smckusick * on UNIBUSes other than 0 can be used. 7917231Smckusick */ 8030547Skarels cudbuf.i_unit = unit; 8132613Sbostic cudbuf.i_ma = (caddr_t)&uda1; 8232613Sbostic cudbuf.i_cc = sizeof(uda1); 83*33543Sbostic ud_ubaddr[uba][io->i_ctlr] = (struct uda1 *)ubasetup(&cudbuf, 2); 845153Ssam } 85*33543Sbostic ubaddr = ud_ubaddr[uba][io->i_ctlr]; 86*33543Sbostic if (udainit[uba][io->i_ctlr] == 0) { 8730547Skarels addr->udaip = 0; 8830547Skarels while ((addr->udasa & UDA_STEP1) == 0) 8917231Smckusick ; 9030547Skarels addr->udasa = UDA_ERR; 9130547Skarels while ((addr->udasa & UDA_STEP2) == 0) 9217231Smckusick ; 9332613Sbostic addr->udasa = (short)&ubaddr->uda1_ca.ca_rspdsc; 9430547Skarels while ((addr->udasa & UDA_STEP3) == 0) 9517231Smckusick ; 9630547Skarels addr->udasa = 9732613Sbostic (short)(((int)&ubaddr->uda1_ca.ca_rspdsc) >> 16); 9830547Skarels while ((addr->udasa & UDA_STEP4) == 0) 9917231Smckusick ; 10030547Skarels addr->udasa = UDA_GO; 10132613Sbostic uda1.uda1_ca.ca_rspdsc = (long)&ubaddr->uda1_rsp.mscp_cmdref; 10232613Sbostic uda1.uda1_ca.ca_cmddsc = (long)&ubaddr->uda1_cmd.mscp_cmdref; 10332613Sbostic /* uda1.uda1_cmd.mscp_cntflgs = 0; */ 10433408Skarels if (udcmd(M_OP_SETCTLRC, io)) { 10532613Sbostic printf("ra: open error, SETCTLRC\n"); 106*33543Sbostic return (ENXIO); 10717231Smckusick } 108*33543Sbostic udainit[uba][io->i_ctlr] = 1; 10927075Skarels } 110*33543Sbostic lp = &ralabel[uba][io->i_ctlr][unit]; 111*33543Sbostic if (ratype[uba][io->i_ctlr][unit] == 0) { 11230547Skarels struct iob tio; 11330547Skarels 114*33543Sbostic uda1.uda1_cmd.mscp_unit = unit; 11533408Skarels if (udcmd(M_OP_ONLINE, io)) { 11632613Sbostic printf("ra: open error, ONLINE\n"); 117*33543Sbostic return (ENXIO); 11817231Smckusick } 119*33543Sbostic ratype[uba][io->i_ctlr][unit] = 120*33543Sbostic uda1.uda1_rsp.mscp_onle.onle_drivetype; 12130547Skarels tio = *io; 12230547Skarels tio.i_bn = LABELSECTOR; 12330547Skarels tio.i_ma = lbuf; 12430547Skarels tio.i_cc = SECTSIZ; 12530547Skarels tio.i_flgs |= F_RDDATA; 12630547Skarels if (rastrategy(&tio, READ) != SECTSIZ) { 127*33543Sbostic printf("ra: can't read disk label\n"); 128*33543Sbostic return (ENXIO); 12930547Skarels } 13033408Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 13133408Skarels if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 13230547Skarels printf("ra%d: unlabeled\n", unit); 13330547Skarels #ifdef COMPAT_42 13430547Skarels ramaptype(io, lp); 13530547Skarels #else 13630547Skarels return (ENXIO); 13730547Skarels #endif 13833408Skarels } 1395153Ssam } 140*33543Sbostic if ((u_int)io->i_part >= lp->d_npartitions || 141*33543Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 142*33543Sbostic return (EPART); 14330547Skarels return (0); 1445153Ssam } 1455153Ssam 14633408Skarels int 14730547Skarels udcmd(op, io) 1485153Ssam int op; 14930547Skarels register struct iob *io; 1505153Ssam { 15133408Skarels register struct uda1 *u = &uda1; 15232613Sbostic register struct mscp *mp; 1535153Ssam int i; 1545153Ssam 15533408Skarels u->uda1_cmd.mscp_opcode = op; 15633408Skarels u->uda1_cmd.mscp_msglen = MSCP_MSGLEN; 15733408Skarels u->uda1_rsp.mscp_msglen = MSCP_MSGLEN; 15833408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 15933408Skarels u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 160*33543Sbostic i = udaddr[io->i_adapt][io->i_ctlr]->udaip; 16133408Skarels mp = &u->uda1_rsp; 1625153Ssam for (;;) { 16333408Skarels if (u->uda1_ca.ca_cmdint) 16433408Skarels u->uda1_ca.ca_cmdint = 0; 16533408Skarels if (u->uda1_ca.ca_rspint == 0) 16632613Sbostic continue; 16733408Skarels u->uda1_ca.ca_rspint = 0; 16832613Sbostic if (mp->mscp_opcode == (op | M_OP_END)) 1695153Ssam break; 17033408Skarels printf("unexpected rsp type %x op %x ignored\n", 17133408Skarels MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode); 17233408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 1735153Ssam } 17432613Sbostic if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS) 17533408Skarels return (-1); 17633408Skarels return (0); 1775153Ssam } 1785153Ssam 17911111Ssam rastrategy(io, func) 1805153Ssam register struct iob *io; 1815153Ssam { 1825153Ssam register struct mscp *mp; 1835153Ssam int ubinfo; 1845153Ssam 1855153Ssam ubinfo = ubasetup(io, 1); 18632613Sbostic mp = &uda1.uda1_cmd; 187*33543Sbostic mp->mscp_unit = io->i_unit; 18832613Sbostic mp->mscp_seq.seq_lbn = io->i_bn; 18932613Sbostic mp->mscp_seq.seq_bytecount = io->i_cc; 19032613Sbostic mp->mscp_seq.seq_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 19133408Skarels if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) { 1925153Ssam printf("ra: I/O error\n"); 1935153Ssam ubafree(io, ubinfo); 1945153Ssam return(-1); 1955153Ssam } 1965153Ssam ubafree(io, ubinfo); 1975153Ssam return(io->i_cc); 1985153Ssam } 19910024Ssam 20030547Skarels #ifdef COMPAT_42 20130547Skarels u_long ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 20232613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 20332613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 }; 20432613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 }; 20530547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 20630547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 20730547Skarels #ifndef UCBRA 20830547Skarels #ifdef RA_COMPAT 20930547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; 21030547Skarels #else 21130547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; 21230547Skarels #endif 21330547Skarels #else 21430547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; 21530547Skarels #endif 21630547Skarels 21732613Sbostic u_long *ra_off[] = { 21832613Sbostic 0, /* 0 = unused */ 21932613Sbostic ra80_off, /* 1 = ra80 */ 22032613Sbostic ra25_off, /* 2 = rc25 removable */ 22132613Sbostic ra25_off, /* 3 = rc25 fixed */ 22232613Sbostic ra60_off, /* 4 = ra60 */ 22332613Sbostic ra81_off, /* 5 = ra81 */ 22432613Sbostic 0, /* 6 = ? */ 22532613Sbostic rx50_off, /* 7 = rx50 */ 22632613Sbostic rd52_off, /* 8 = rd52 */ 22732613Sbostic rd53_off, /* 9 = rd53 */ 22832613Sbostic }; 22932613Sbostic 23033408Skarels #define NOFFS (sizeof(ra_off)/sizeof(ra_off[0])) 23132613Sbostic 23230547Skarels ramaptype(io, lp) 23330547Skarels register struct iob *io; 23430547Skarels register struct disklabel *lp; 23530547Skarels { 23630547Skarels register struct partition *pp; 23733408Skarels register u_int i; 23830547Skarels register u_long *off; 23930547Skarels 240*33543Sbostic if ((i = ratype[io->i_adapt][io->i_ctlr][io->i_unit]) >= NOFFS || 241*33543Sbostic (off = ra_off[i]) == 0) { 24232613Sbostic printf("ra%d: ra type %d unsupported\n", io->i_unit, i); 24330547Skarels lp->d_npartitions = 0; 24430547Skarels return; 24530547Skarels } 24630547Skarels lp->d_npartitions = 8; 24732613Sbostic for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++) 24830547Skarels pp->p_offset = *off++; 24930547Skarels } 25030547Skarels #endif 251