1 /* $NetBSD: tmscp.c,v 1.3 1999/06/30 18:19:26 ragge Exp $ */ 2 /* 3 * Copyright (c) 1995 Ludd, University of Lule}, Sweden. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed at Ludd, University of Lule}. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* All bugs are subject to removal without further notice */ 33 34 #define NRSP 0 /* Kludge */ 35 #define NCMD 0 /* Kludge */ 36 37 #include "sys/param.h" 38 #include "sys/disklabel.h" 39 40 #include "lib/libsa/stand.h" 41 42 #include "../include/pte.h" 43 #include "dev/mscp/mscp.h" 44 #include "dev/mscp/mscpreg.h" 45 46 #include "vaxstand.h" 47 48 static command(int,int); 49 50 /* 51 * These routines for TMSCP tape standalone boot is very simple, 52 * assuming a lots of thing like that we only working at one tape at 53 * a time, no separate routines for uba driver etc.. 54 * This code is directly copied from ra disk driver. 55 */ 56 57 struct ra_softc { 58 int udaddr; 59 int ubaddr; 60 int unit; 61 }; 62 63 static volatile struct uda { 64 struct mscp_1ca uda_ca; /* communications area */ 65 struct mscp uda_rsp; /* response packets */ 66 struct mscp uda_cmd; /* command packets */ 67 } uda; 68 69 struct udadevice { 70 short udaip; 71 short udasa; 72 }; 73 74 static volatile struct uda *ubauda; 75 static volatile struct udadevice *udacsr; 76 static struct ra_softc ra_softc; 77 static int curblock; 78 79 80 tmscpopen(f, adapt, ctlr, unit, part) 81 struct open_file *f; 82 int ctlr, unit, part; 83 { 84 char *msg; 85 extern u_int tmsaddr; 86 volatile struct ra_softc *ra=&ra_softc; 87 volatile u_int *nisse; 88 unsigned short johan; 89 int i,err; 90 91 curblock = 0; 92 if(adapt>nuba) return(EADAPT); 93 if(ctlr>nuda) return(ECTLR); 94 ra->udaddr=uioaddr[adapt]+tmsaddr; 95 ra->ubaddr=(int)ubaaddr[adapt]; 96 ra->unit=unit; 97 udacsr=(void*)ra->udaddr; 98 nisse=((u_int *)ubaaddr[adapt]) + 512; 99 nisse[494]=PG_V|(((u_int)&uda)>>9); 100 nisse[495]=nisse[494]+1; 101 ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff); 102 103 /* 104 * Init of this tmscp ctlr. 105 */ 106 udacsr->udaip=0; /* Start init */ 107 while((udacsr->udasa&MP_STEP1) == 0); 108 udacsr->udasa=0x8000; 109 while((udacsr->udasa&MP_STEP2) == 0); 110 johan=(((u_int)ubauda)&0xffff)+8; 111 udacsr->udasa=johan; 112 while((udacsr->udasa&MP_STEP3) == 0); 113 udacsr->udasa=3; 114 while((udacsr->udasa&MP_STEP4) == 0); 115 udacsr->udasa=0x0001; 116 117 uda.uda_ca.ca_rspdsc=(int)&ubauda->uda_rsp.mscp_cmdref; 118 uda.uda_ca.ca_cmddsc=(int)&ubauda->uda_cmd.mscp_cmdref; 119 uda.uda_cmd.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_cmddsc; 120 uda.uda_rsp.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_rspdsc; 121 uda.uda_cmd.mscp_vcid = 1; 122 uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0; 123 124 command(M_OP_SETCTLRC, 0); 125 uda.uda_cmd.mscp_unit=ra->unit; 126 command(M_OP_ONLINE, 0); 127 128 if (part) { 129 uda.uda_cmd.mscp_un.un_seq.seq_buffer = part; 130 command(M_OP_POS, 0); 131 uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0; 132 } 133 134 f->f_devdata=(void *)ra; 135 return(0); 136 } 137 138 static 139 command(cmd, arg) 140 { 141 volatile int hej; 142 143 uda.uda_cmd.mscp_opcode = cmd; 144 uda.uda_cmd.mscp_modifier = arg; 145 146 uda.uda_cmd.mscp_msglen = MSCP_MSGLEN; 147 uda.uda_rsp.mscp_msglen = MSCP_MSGLEN; 148 149 uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; 150 uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; 151 hej = udacsr->udaip; 152 while (uda.uda_ca.ca_rspdsc < 0) { 153 if (uda.uda_ca.ca_cmdint) 154 uda.uda_ca.ca_cmdint = 0; 155 } 156 157 } 158 159 tmscpstrategy(ra, func, dblk, size, buf, rsize) 160 struct ra_softc *ra; 161 int func; 162 daddr_t dblk; 163 char *buf; 164 u_int size, *rsize; 165 { 166 u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn; 167 volatile struct udadevice *udadev=(void*)ra->udaddr; 168 volatile u_int *ptmapp = (u_int *)ra->ubaddr + 512; 169 volatile int hej; 170 171 pfnum=(u_int)buf>>VAX_PGSHIFT; 172 173 for(mapnr=0, nsize=size;(nsize+VAX_NBPG)>0;nsize-=VAX_NBPG) 174 ptmapp[mapnr++]=PG_V|pfnum++; 175 176 /* 177 * First position tape. Remember where we are. 178 */ 179 if (dblk < curblock) { 180 uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk; 181 command(M_OP_POS, 12); /* 12 == step block backward */ 182 } else { 183 uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock; 184 command(M_OP_POS, 4); /* 4 == step block forward */ 185 } 186 curblock = size/512 + dblk; 187 188 /* 189 * Read in the number of blocks we need. 190 * Why doesn't read of multiple blocks work????? 191 */ 192 for (i = 0 ; i < size/512 ; i++) { 193 uda.uda_cmd.mscp_seq.seq_lbn = 1; 194 uda.uda_cmd.mscp_seq.seq_bytecount = 512; 195 uda.uda_cmd.mscp_seq.seq_buffer = 196 (((u_int)buf) & 0x1ff) + i * 512; 197 uda.uda_cmd.mscp_unit = ra->unit; 198 command(M_OP_READ, 0); 199 } 200 201 *rsize=size; 202 return 0; 203 } 204