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