xref: /netbsd/sys/arch/vax/boot/boot/tmscp.c (revision bf9ec67e)
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