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