1*17231Smckusick /* uda.c 6.2 84/10/04 */ 25153Ssam 35153Ssam /* 45153Ssam * UDA50/RAxx disk device driver 55153Ssam */ 69806Ssam #include "../machine/pte.h" 75153Ssam 85153Ssam #include "../h/param.h" 95153Ssam #include "../h/inode.h" 107447Sroot #include "../h/fs.h" 119186Ssam 125153Ssam #include "saio.h" 135153Ssam #include "savax.h" 145153Ssam 155153Ssam /* 165153Ssam * Parameters for the communications area 175153Ssam */ 185153Ssam #define NRSPL2 0 195153Ssam #define NCMDL2 0 205153Ssam #define NRSP (1<<NRSPL2) 215153Ssam #define NCMD (1<<NCMDL2) 225153Ssam 239186Ssam #include "../vaxuba/udareg.h" 249186Ssam #include "../vaxuba/ubareg.h" 259186Ssam #include "../vax/mscp.h" 265153Ssam 2711181Ssam u_short udastd[] = { 0772150 }; 285153Ssam 295153Ssam struct iob cudbuf; 305153Ssam 315153Ssam struct udadevice *udaddr = 0; 325153Ssam 335153Ssam struct uda { 345153Ssam struct udaca uda_ca; 355153Ssam struct mscp uda_rsp; 365153Ssam struct mscp uda_cmd; 375153Ssam } uda; 385153Ssam 395153Ssam struct uda *ud_ubaddr; /* Unibus address of uda structure */ 405153Ssam 415153Ssam int uda_off[] = { 0, 15884, 0, -1, -1, -1, 49324, 131404 }; 425153Ssam 435153Ssam struct mscp *udcmd(); 445153Ssam 4511111Ssam raopen(io) 465153Ssam register struct iob *io; 475153Ssam { 485153Ssam register struct mscp *mp; 49*17231Smckusick static int udainit; 505153Ssam int i; 515153Ssam 525153Ssam if (udaddr == 0) 535153Ssam udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]); 545153Ssam if (ud_ubaddr == 0) { 55*17231Smckusick /* 56*17231Smckusick * Initialise cudbuf.i_unit so that controllers 57*17231Smckusick * on UNIBUSes other than 0 can be used. 58*17231Smckusick */ 59*17231Smckusick cudbuf.i_unit = io->i_unit; 605153Ssam cudbuf.i_ma = (caddr_t)&uda; 615153Ssam cudbuf.i_cc = sizeof(uda); 625153Ssam ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2); 635153Ssam } 64*17231Smckusick if (udainit == 0) { 65*17231Smckusick udaddr->udaip = 0; 66*17231Smckusick while ((udaddr->udasa & UDA_STEP1) == 0) 67*17231Smckusick ; 68*17231Smckusick udaddr->udasa = UDA_ERR; 69*17231Smckusick while ((udaddr->udasa & UDA_STEP2) == 0) 70*17231Smckusick ; 71*17231Smckusick udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase; 72*17231Smckusick while ((udaddr->udasa & UDA_STEP3) == 0) 73*17231Smckusick ; 74*17231Smckusick udaddr->udasa = 75*17231Smckusick (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16); 76*17231Smckusick while ((udaddr->udasa & UDA_STEP4) == 0) 77*17231Smckusick ; 78*17231Smckusick udaddr->udasa = UDA_GO; 79*17231Smckusick uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref; 80*17231Smckusick uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref; 81*17231Smckusick uda.uda_cmd.mscp_cntflgs = 0; 82*17231Smckusick if (udcmd(M_OP_STCON) == 0) { 83*17231Smckusick _stop("ra: open error, STCON"); 84*17231Smckusick return; 85*17231Smckusick } 86*17231Smckusick uda.uda_cmd.mscp_unit = io->i_unit&7; 87*17231Smckusick if (udcmd(M_OP_ONLIN) == 0) { 88*17231Smckusick _stop("ra: open error, ONLIN"); 89*17231Smckusick return; 90*17231Smckusick } 91*17231Smckusick udainit = 1; 925153Ssam } 935153Ssam if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1) 945153Ssam _stop("ra: bad unit"); 955153Ssam io->i_boff = uda_off[io->i_boff]; 965153Ssam } 975153Ssam 985153Ssam struct mscp * 995153Ssam udcmd(op) 1005153Ssam int op; 1015153Ssam { 1025153Ssam struct mscp *mp; 1035153Ssam int i; 1045153Ssam 1055153Ssam uda.uda_cmd.mscp_opcode = op; 1065153Ssam uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp); 1075153Ssam uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp); 1085153Ssam uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT; 1095153Ssam uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT; 1105153Ssam i = udaddr->udaip; 1115153Ssam for (;;) { 1125153Ssam if (uda.uda_ca.ca_cmdint) 1135153Ssam uda.uda_ca.ca_cmdint = 0; 1145153Ssam if (uda.uda_ca.ca_rspint) 1155153Ssam break; 1165153Ssam } 1175153Ssam uda.uda_ca.ca_rspint = 0; 1185153Ssam mp = &uda.uda_rsp; 1195153Ssam if (mp->mscp_opcode != (op|M_OP_END) || 1205153Ssam (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) 1215153Ssam return(0); 1225153Ssam return(mp); 1235153Ssam } 1245153Ssam 12511111Ssam rastrategy(io, func) 1265153Ssam register struct iob *io; 1275153Ssam { 1285153Ssam register struct mscp *mp; 1295153Ssam int ubinfo; 1305153Ssam 1315153Ssam ubinfo = ubasetup(io, 1); 1325153Ssam mp = &uda.uda_cmd; 1335153Ssam mp->mscp_lbn = io->i_bn; 1345153Ssam mp->mscp_unit = io->i_unit&7; 1355153Ssam mp->mscp_bytecnt = io->i_cc; 1365153Ssam mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 1375153Ssam if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) { 1385153Ssam printf("ra: I/O error\n"); 1395153Ssam ubafree(io, ubinfo); 1405153Ssam return(-1); 1415153Ssam } 1425153Ssam ubafree(io, ubinfo); 1435153Ssam return(io->i_cc); 1445153Ssam } 14510024Ssam 14610024Ssam /*ARGSUSED*/ 14711111Ssam raioctl(io, cmd, arg) 14810024Ssam struct iob *io; 14910024Ssam int cmd; 15010024Ssam caddr_t arg; 15110024Ssam { 15210024Ssam 15310024Ssam return (ECMD); 15410024Ssam } 155