1*5153Ssam /* uda.c 4.1 81/12/01 */ 2*5153Ssam 3*5153Ssam /* 4*5153Ssam * UDA50/RAxx disk device driver 5*5153Ssam */ 6*5153Ssam 7*5153Ssam #include "../h/param.h" 8*5153Ssam #include "../h/inode.h" 9*5153Ssam #include "../h/pte.h" 10*5153Ssam #include "../h/ubareg.h" 11*5153Ssam #include "saio.h" 12*5153Ssam #include "savax.h" 13*5153Ssam 14*5153Ssam /* 15*5153Ssam * Parameters for the communications area 16*5153Ssam */ 17*5153Ssam #define NRSPL2 0 18*5153Ssam #define NCMDL2 0 19*5153Ssam #define NRSP (1<<NRSPL2) 20*5153Ssam #define NCMD (1<<NCMDL2) 21*5153Ssam 22*5153Ssam #include "../h/udareg.h" 23*5153Ssam #include "../h/mscp.h" 24*5153Ssam 25*5153Ssam 26*5153Ssam u_short udastd[] = { 0777550 }; 27*5153Ssam 28*5153Ssam struct iob cudbuf; 29*5153Ssam 30*5153Ssam struct udadevice *udaddr = 0; 31*5153Ssam 32*5153Ssam struct uda { 33*5153Ssam struct udaca uda_ca; 34*5153Ssam struct mscp uda_rsp; 35*5153Ssam struct mscp uda_cmd; 36*5153Ssam } uda; 37*5153Ssam 38*5153Ssam struct uda *ud_ubaddr; /* Unibus address of uda structure */ 39*5153Ssam 40*5153Ssam int uda_off[] = { 0, 15884, 0, -1, -1, -1, 49324, 131404 }; 41*5153Ssam 42*5153Ssam struct mscp *udcmd(); 43*5153Ssam 44*5153Ssam udopen(io) 45*5153Ssam register struct iob *io; 46*5153Ssam { 47*5153Ssam register struct mscp *mp; 48*5153Ssam int i; 49*5153Ssam 50*5153Ssam if (udaddr == 0) 51*5153Ssam udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]); 52*5153Ssam if (ud_ubaddr == 0) { 53*5153Ssam cudbuf.i_ma = (caddr_t)&uda; 54*5153Ssam cudbuf.i_cc = sizeof(uda); 55*5153Ssam ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2); 56*5153Ssam } 57*5153Ssam udaddr->udaip = 0; 58*5153Ssam while ((udaddr->udasa & UDA_STEP1) == 0) 59*5153Ssam ; 60*5153Ssam udaddr->udasa = UDA_ERR; 61*5153Ssam while ((udaddr->udasa & UDA_STEP2) == 0) 62*5153Ssam ; 63*5153Ssam udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase; 64*5153Ssam while ((udaddr->udasa & UDA_STEP3) == 0) 65*5153Ssam ; 66*5153Ssam udaddr->udasa = (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16); 67*5153Ssam while ((udaddr->udasa & UDA_STEP4) == 0) 68*5153Ssam ; 69*5153Ssam udaddr->udasa = UDA_GO; 70*5153Ssam uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref; 71*5153Ssam uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref; 72*5153Ssam uda.uda_cmd.mscp_cntflgs = 0; 73*5153Ssam if (udcmd(M_OP_STCON) == 0) { 74*5153Ssam _stop("ra: open error, STCON"); 75*5153Ssam return; 76*5153Ssam } 77*5153Ssam uda.uda_cmd.mscp_unit = io->i_unit&7; 78*5153Ssam if (udcmd(M_OP_ONLIN) == 0) { 79*5153Ssam _stop("ra: open error, ONLIN"); 80*5153Ssam return; 81*5153Ssam } 82*5153Ssam if (io->i_boff < 0 || io->i_boff > 7 || uda_off[io->i_boff] == -1) 83*5153Ssam _stop("ra: bad unit"); 84*5153Ssam io->i_boff = uda_off[io->i_boff]; 85*5153Ssam } 86*5153Ssam 87*5153Ssam struct mscp * 88*5153Ssam udcmd(op) 89*5153Ssam int op; 90*5153Ssam { 91*5153Ssam struct mscp *mp; 92*5153Ssam int i; 93*5153Ssam 94*5153Ssam uda.uda_cmd.mscp_opcode = op; 95*5153Ssam uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp); 96*5153Ssam uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp); 97*5153Ssam uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT; 98*5153Ssam uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT; 99*5153Ssam i = udaddr->udaip; 100*5153Ssam for (;;) { 101*5153Ssam if (uda.uda_ca.ca_cmdint) 102*5153Ssam uda.uda_ca.ca_cmdint = 0; 103*5153Ssam if (uda.uda_ca.ca_rspint) 104*5153Ssam break; 105*5153Ssam } 106*5153Ssam uda.uda_ca.ca_rspint = 0; 107*5153Ssam mp = &uda.uda_rsp; 108*5153Ssam if (mp->mscp_opcode != (op|M_OP_END) || 109*5153Ssam (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) 110*5153Ssam return(0); 111*5153Ssam return(mp); 112*5153Ssam } 113*5153Ssam 114*5153Ssam udstrategy(io, func) 115*5153Ssam register struct iob *io; 116*5153Ssam { 117*5153Ssam register struct mscp *mp; 118*5153Ssam int ubinfo; 119*5153Ssam 120*5153Ssam ubinfo = ubasetup(io, 1); 121*5153Ssam mp = &uda.uda_cmd; 122*5153Ssam mp->mscp_lbn = io->i_bn; 123*5153Ssam mp->mscp_unit = io->i_unit&7; 124*5153Ssam mp->mscp_bytecnt = io->i_cc; 125*5153Ssam mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24); 126*5153Ssam if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) { 127*5153Ssam printf("ra: I/O error\n"); 128*5153Ssam ubafree(io, ubinfo); 129*5153Ssam return(-1); 130*5153Ssam } 131*5153Ssam ubafree(io, ubinfo); 132*5153Ssam return(io->i_cc); 133*5153Ssam } 134