123247Smckusick /* 223247Smckusick * Copyright (c) 1982 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*27075Skarels * @(#)uda.c 6.4 (Berkeley) 04/14/86 723247Smckusick */ 85153Ssam 95153Ssam /* 105153Ssam * UDA50/RAxx disk device driver 115153Ssam */ 129806Ssam #include "../machine/pte.h" 135153Ssam 145153Ssam #include "../h/param.h" 155153Ssam #include "../h/inode.h" 167447Sroot #include "../h/fs.h" 179186Ssam 185153Ssam #include "saio.h" 195153Ssam #include "savax.h" 205153Ssam 21*27075Skarels #define NRA 4 225153Ssam /* 235153Ssam * Parameters for the communications area 245153Ssam */ 255153Ssam #define NRSPL2 0 265153Ssam #define NCMDL2 0 275153Ssam #define NRSP (1<<NRSPL2) 285153Ssam #define NCMD (1<<NCMDL2) 295153Ssam 309186Ssam #include "../vaxuba/udareg.h" 319186Ssam #include "../vaxuba/ubareg.h" 329186Ssam #include "../vax/mscp.h" 335153Ssam 3411181Ssam u_short udastd[] = { 0772150 }; 355153Ssam 365153Ssam struct iob cudbuf; 375153Ssam 385153Ssam struct udadevice *udaddr = 0; 395153Ssam 405153Ssam struct uda { 415153Ssam struct udaca uda_ca; 425153Ssam struct mscp uda_rsp; 435153Ssam struct mscp uda_cmd; 445153Ssam } uda; 455153Ssam 465153Ssam struct uda *ud_ubaddr; /* Unibus address of uda structure */ 475153Ssam 48*27075Skarels int ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; 49*27075Skarels int ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; 50*27075Skarels int ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 }; 51*27075Skarels #ifndef UCBRA 52*27075Skarels #ifdef RA_COMPAT 53*27075Skarels int ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 }; 54*27075Skarels #else 55*27075Skarels int ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 }; 56*27075Skarels #endif 57*27075Skarels #else 58*27075Skarels int ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 }; 59*27075Skarels #endif 605153Ssam 615153Ssam struct mscp *udcmd(); 62*27075Skarels static int ratype[NRA]; 635153Ssam 6411111Ssam raopen(io) 655153Ssam register struct iob *io; 665153Ssam { 675153Ssam register struct mscp *mp; 68*27075Skarels static int udainit, udadriveinit[NRA]; 695153Ssam int i; 70*27075Skarels daddr_t off; 715153Ssam 725153Ssam if (udaddr == 0) 735153Ssam udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]); 745153Ssam if (ud_ubaddr == 0) { 7517231Smckusick /* 7617231Smckusick * Initialise cudbuf.i_unit so that controllers 7717231Smckusick * on UNIBUSes other than 0 can be used. 7817231Smckusick */ 7917231Smckusick cudbuf.i_unit = io->i_unit; 805153Ssam cudbuf.i_ma = (caddr_t)&uda; 815153Ssam cudbuf.i_cc = sizeof(uda); 825153Ssam ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2); 835153Ssam } 8417231Smckusick if (udainit == 0) { 8517231Smckusick udaddr->udaip = 0; 8617231Smckusick while ((udaddr->udasa & UDA_STEP1) == 0) 8717231Smckusick ; 8817231Smckusick udaddr->udasa = UDA_ERR; 8917231Smckusick while ((udaddr->udasa & UDA_STEP2) == 0) 9017231Smckusick ; 9117231Smckusick udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase; 9217231Smckusick while ((udaddr->udasa & UDA_STEP3) == 0) 9317231Smckusick ; 9417231Smckusick udaddr->udasa = 9517231Smckusick (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16); 9617231Smckusick while ((udaddr->udasa & UDA_STEP4) == 0) 9717231Smckusick ; 9817231Smckusick udaddr->udasa = UDA_GO; 9917231Smckusick uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref; 10017231Smckusick uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref; 10117231Smckusick uda.uda_cmd.mscp_cntflgs = 0; 10217231Smckusick if (udcmd(M_OP_STCON) == 0) { 10317231Smckusick _stop("ra: open error, STCON"); 10417231Smckusick return; 10517231Smckusick } 106*27075Skarels } 107*27075Skarels i = io->i_unit & 7; 108*27075Skarels if (udadriveinit[i] == 0) { 109*27075Skarels uda.uda_cmd.mscp_unit = i; 11017231Smckusick if (udcmd(M_OP_ONLIN) == 0) { 11117231Smckusick _stop("ra: open error, ONLIN"); 11217231Smckusick return; 11317231Smckusick } 11417231Smckusick udainit = 1; 1155153Ssam } 116*27075Skarels if (io->i_boff < 0 || io->i_boff > 7) 1175153Ssam _stop("ra: bad unit"); 118*27075Skarels 119*27075Skarels switch (ratype[i]) { 120*27075Skarels case 25: 121*27075Skarels off = ra25_off[io->i_boff]; 122*27075Skarels break; 123*27075Skarels case 60: 124*27075Skarels off = ra60_off[io->i_boff]; 125*27075Skarels break; 126*27075Skarels case 80: 127*27075Skarels off = ra80_off[io->i_boff]; 128*27075Skarels break; 129*27075Skarels case 81: 130*27075Skarels off = ra81_off[io->i_boff]; 131*27075Skarels break; 132*27075Skarels default: 133*27075Skarels printf("uda%d: don't support ra%d's\n", i, ratype[i]); 134*27075Skarels off = -1; 135*27075Skarels break; 136*27075Skarels } 137*27075Skarels if (off == -1) 138*27075Skarels _stop("ra: bad partition"); 139*27075Skarels io->i_boff = off; 1405153Ssam } 1415153Ssam 1425153Ssam struct mscp * 1435153Ssam udcmd(op) 1445153Ssam int op; 1455153Ssam { 1465153Ssam struct mscp *mp; 1475153Ssam int i; 1485153Ssam 1495153Ssam uda.uda_cmd.mscp_opcode = op; 1505153Ssam uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp); 1515153Ssam uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp); 1525153Ssam uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT; 1535153Ssam uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT; 1545153Ssam i = udaddr->udaip; 1555153Ssam for (;;) { 1565153Ssam if (uda.uda_ca.ca_cmdint) 1575153Ssam uda.uda_ca.ca_cmdint = 0; 1585153Ssam if (uda.uda_ca.ca_rspint) 1595153Ssam break; 1605153Ssam } 1615153Ssam uda.uda_ca.ca_rspint = 0; 1625153Ssam mp = &uda.uda_rsp; 1635153Ssam if (mp->mscp_opcode != (op|M_OP_END) || 1645153Ssam (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) 1655153Ssam return(0); 166*27075Skarels if (mp->mscp_opcode == (M_OP_ONLIN|M_OP_END)) 167*27075Skarels ratype[uda.uda_cmd.mscp_unit] = mp->mscp_mediaid & 0x7f; 1685153Ssam return(mp); 1695153Ssam } 1705153Ssam 17111111Ssam rastrategy(io, func) 1725153Ssam register struct iob *io; 1735153Ssam { 1745153Ssam register struct mscp *mp; 1755153Ssam int ubinfo; 1765153Ssam 1775153Ssam ubinfo = ubasetup(io, 1); 1785153Ssam mp = &uda.uda_cmd; 1795153Ssam mp->mscp_lbn = io->i_bn; 1805153Ssam mp->mscp_unit = io->i_unit&7; 1815153Ssam mp->mscp_bytecnt = io->i_cc; 1825153Ssam mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 1835153Ssam if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) { 1845153Ssam printf("ra: I/O error\n"); 1855153Ssam ubafree(io, ubinfo); 1865153Ssam return(-1); 1875153Ssam } 1885153Ssam ubafree(io, ubinfo); 1895153Ssam return(io->i_cc); 1905153Ssam } 19110024Ssam 19210024Ssam /*ARGSUSED*/ 19311111Ssam raioctl(io, cmd, arg) 19410024Ssam struct iob *io; 19510024Ssam int cmd; 19610024Ssam caddr_t arg; 19710024Ssam { 19810024Ssam 19910024Ssam return (ECMD); 20010024Ssam } 201