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