1*23247Smckusick /* 2*23247Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23247Smckusick * All rights reserved. The Berkeley software License Agreement 4*23247Smckusick * specifies the terms and conditions for redistribution. 5*23247Smckusick * 6*23247Smckusick * @(#)uda.c 6.3 (Berkeley) 06/08/85 7*23247Smckusick */ 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 215153Ssam /* 225153Ssam * Parameters for the communications area 235153Ssam */ 245153Ssam #define NRSPL2 0 255153Ssam #define NCMDL2 0 265153Ssam #define NRSP (1<<NRSPL2) 275153Ssam #define NCMD (1<<NCMDL2) 285153Ssam 299186Ssam #include "../vaxuba/udareg.h" 309186Ssam #include "../vaxuba/ubareg.h" 319186Ssam #include "../vax/mscp.h" 325153Ssam 3311181Ssam u_short udastd[] = { 0772150 }; 345153Ssam 355153Ssam struct iob cudbuf; 365153Ssam 375153Ssam struct udadevice *udaddr = 0; 385153Ssam 395153Ssam struct uda { 405153Ssam struct udaca uda_ca; 415153Ssam struct mscp uda_rsp; 425153Ssam struct mscp uda_cmd; 435153Ssam } uda; 445153Ssam 455153Ssam struct uda *ud_ubaddr; /* Unibus address of uda structure */ 465153Ssam 475153Ssam int uda_off[] = { 0, 15884, 0, -1, -1, -1, 49324, 131404 }; 485153Ssam 495153Ssam struct mscp *udcmd(); 505153Ssam 5111111Ssam raopen(io) 525153Ssam register struct iob *io; 535153Ssam { 545153Ssam register struct mscp *mp; 5517231Smckusick static int udainit; 565153Ssam int i; 575153Ssam 585153Ssam if (udaddr == 0) 595153Ssam udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]); 605153Ssam if (ud_ubaddr == 0) { 6117231Smckusick /* 6217231Smckusick * Initialise cudbuf.i_unit so that controllers 6317231Smckusick * on UNIBUSes other than 0 can be used. 6417231Smckusick */ 6517231Smckusick cudbuf.i_unit = io->i_unit; 665153Ssam cudbuf.i_ma = (caddr_t)&uda; 675153Ssam cudbuf.i_cc = sizeof(uda); 685153Ssam ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2); 695153Ssam } 7017231Smckusick if (udainit == 0) { 7117231Smckusick udaddr->udaip = 0; 7217231Smckusick while ((udaddr->udasa & UDA_STEP1) == 0) 7317231Smckusick ; 7417231Smckusick udaddr->udasa = UDA_ERR; 7517231Smckusick while ((udaddr->udasa & UDA_STEP2) == 0) 7617231Smckusick ; 7717231Smckusick udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase; 7817231Smckusick while ((udaddr->udasa & UDA_STEP3) == 0) 7917231Smckusick ; 8017231Smckusick udaddr->udasa = 8117231Smckusick (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16); 8217231Smckusick while ((udaddr->udasa & UDA_STEP4) == 0) 8317231Smckusick ; 8417231Smckusick udaddr->udasa = UDA_GO; 8517231Smckusick uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref; 8617231Smckusick uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref; 8717231Smckusick uda.uda_cmd.mscp_cntflgs = 0; 8817231Smckusick if (udcmd(M_OP_STCON) == 0) { 8917231Smckusick _stop("ra: open error, STCON"); 9017231Smckusick return; 9117231Smckusick } 9217231Smckusick uda.uda_cmd.mscp_unit = io->i_unit&7; 9317231Smckusick if (udcmd(M_OP_ONLIN) == 0) { 9417231Smckusick _stop("ra: open error, ONLIN"); 9517231Smckusick return; 9617231Smckusick } 9717231Smckusick udainit = 1; 985153Ssam } 995153Ssam if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1) 1005153Ssam _stop("ra: bad unit"); 1015153Ssam io->i_boff = uda_off[io->i_boff]; 1025153Ssam } 1035153Ssam 1045153Ssam struct mscp * 1055153Ssam udcmd(op) 1065153Ssam int op; 1075153Ssam { 1085153Ssam struct mscp *mp; 1095153Ssam int i; 1105153Ssam 1115153Ssam uda.uda_cmd.mscp_opcode = op; 1125153Ssam uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp); 1135153Ssam uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp); 1145153Ssam uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT; 1155153Ssam uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT; 1165153Ssam i = udaddr->udaip; 1175153Ssam for (;;) { 1185153Ssam if (uda.uda_ca.ca_cmdint) 1195153Ssam uda.uda_ca.ca_cmdint = 0; 1205153Ssam if (uda.uda_ca.ca_rspint) 1215153Ssam break; 1225153Ssam } 1235153Ssam uda.uda_ca.ca_rspint = 0; 1245153Ssam mp = &uda.uda_rsp; 1255153Ssam if (mp->mscp_opcode != (op|M_OP_END) || 1265153Ssam (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) 1275153Ssam return(0); 1285153Ssam return(mp); 1295153Ssam } 1305153Ssam 13111111Ssam rastrategy(io, func) 1325153Ssam register struct iob *io; 1335153Ssam { 1345153Ssam register struct mscp *mp; 1355153Ssam int ubinfo; 1365153Ssam 1375153Ssam ubinfo = ubasetup(io, 1); 1385153Ssam mp = &uda.uda_cmd; 1395153Ssam mp->mscp_lbn = io->i_bn; 1405153Ssam mp->mscp_unit = io->i_unit&7; 1415153Ssam mp->mscp_bytecnt = io->i_cc; 1425153Ssam mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 1435153Ssam if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) { 1445153Ssam printf("ra: I/O error\n"); 1455153Ssam ubafree(io, ubinfo); 1465153Ssam return(-1); 1475153Ssam } 1485153Ssam ubafree(io, ubinfo); 1495153Ssam return(io->i_cc); 1505153Ssam } 15110024Ssam 15210024Ssam /*ARGSUSED*/ 15311111Ssam raioctl(io, cmd, arg) 15410024Ssam struct iob *io; 15510024Ssam int cmd; 15610024Ssam caddr_t arg; 15710024Ssam { 15810024Ssam 15910024Ssam return (ECMD); 16010024Ssam } 161