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