1*9806Ssam /* uda.c 4.4 82/12/17 */ 25153Ssam 35153Ssam /* 45153Ssam * UDA50/RAxx disk device driver 55153Ssam */ 6*9806Ssam #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 275153Ssam u_short udastd[] = { 0777550 }; 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 455153Ssam udopen(io) 465153Ssam register struct iob *io; 475153Ssam { 485153Ssam register struct mscp *mp; 495153Ssam int i; 505153Ssam 515153Ssam if (udaddr == 0) 525153Ssam udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]); 535153Ssam if (ud_ubaddr == 0) { 545153Ssam cudbuf.i_ma = (caddr_t)&uda; 555153Ssam cudbuf.i_cc = sizeof(uda); 565153Ssam ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2); 575153Ssam } 585153Ssam udaddr->udaip = 0; 595153Ssam while ((udaddr->udasa & UDA_STEP1) == 0) 605153Ssam ; 615153Ssam udaddr->udasa = UDA_ERR; 625153Ssam while ((udaddr->udasa & UDA_STEP2) == 0) 635153Ssam ; 645153Ssam udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase; 655153Ssam while ((udaddr->udasa & UDA_STEP3) == 0) 665153Ssam ; 675153Ssam udaddr->udasa = (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16); 685153Ssam while ((udaddr->udasa & UDA_STEP4) == 0) 695153Ssam ; 705153Ssam udaddr->udasa = UDA_GO; 715153Ssam uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref; 725153Ssam uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref; 735153Ssam uda.uda_cmd.mscp_cntflgs = 0; 745153Ssam if (udcmd(M_OP_STCON) == 0) { 755153Ssam _stop("ra: open error, STCON"); 765153Ssam return; 775153Ssam } 785153Ssam uda.uda_cmd.mscp_unit = io->i_unit&7; 795153Ssam if (udcmd(M_OP_ONLIN) == 0) { 805153Ssam _stop("ra: open error, ONLIN"); 815153Ssam return; 825153Ssam } 835153Ssam if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1) 845153Ssam _stop("ra: bad unit"); 855153Ssam io->i_boff = uda_off[io->i_boff]; 865153Ssam } 875153Ssam 885153Ssam struct mscp * 895153Ssam udcmd(op) 905153Ssam int op; 915153Ssam { 925153Ssam struct mscp *mp; 935153Ssam int i; 945153Ssam 955153Ssam uda.uda_cmd.mscp_opcode = op; 965153Ssam uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp); 975153Ssam uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp); 985153Ssam uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT; 995153Ssam uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT; 1005153Ssam i = udaddr->udaip; 1015153Ssam for (;;) { 1025153Ssam if (uda.uda_ca.ca_cmdint) 1035153Ssam uda.uda_ca.ca_cmdint = 0; 1045153Ssam if (uda.uda_ca.ca_rspint) 1055153Ssam break; 1065153Ssam } 1075153Ssam uda.uda_ca.ca_rspint = 0; 1085153Ssam mp = &uda.uda_rsp; 1095153Ssam if (mp->mscp_opcode != (op|M_OP_END) || 1105153Ssam (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) 1115153Ssam return(0); 1125153Ssam return(mp); 1135153Ssam } 1145153Ssam 1155153Ssam udstrategy(io, func) 1165153Ssam register struct iob *io; 1175153Ssam { 1185153Ssam register struct mscp *mp; 1195153Ssam int ubinfo; 1205153Ssam 1215153Ssam ubinfo = ubasetup(io, 1); 1225153Ssam mp = &uda.uda_cmd; 1235153Ssam mp->mscp_lbn = io->i_bn; 1245153Ssam mp->mscp_unit = io->i_unit&7; 1255153Ssam mp->mscp_bytecnt = io->i_cc; 1265153Ssam mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 1275153Ssam if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) { 1285153Ssam printf("ra: I/O error\n"); 1295153Ssam ubafree(io, ubinfo); 1305153Ssam return(-1); 1315153Ssam } 1325153Ssam ubafree(io, ubinfo); 1335153Ssam return(io->i_cc); 1345153Ssam } 135