dev_tape.c revision 1.2 1 /* $NetBSD: dev_tape.c,v 1.2 1997/12/17 21:28:02 scw Exp $ */
2
3 /*
4 * Copyright (c) 1993 Paul Kranenburg
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Paul Kranenburg.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * This module implements a "raw device" interface suitable for
35 * use by the stand-alone I/O library UFS file-system code, and
36 * possibly for direct access (i.e. boot from tape).
37 */
38
39 #include <sys/types.h>
40 #include <machine/prom.h>
41
42 #include "stand.h"
43 #include "libsa.h"
44
45
46 extern int debug;
47
48 struct mvmeprom_dskio tape_ioreq;
49
50 static int hackprom_diskrd(struct mvmeprom_dskio *);
51
52 /*
53 * This is a special version of devopen() for tape boot.
54 * In this version, the file name is a numeric string of
55 * one digit, which is passed to the device open so it
56 * can open the appropriate tape segment.
57 */
58 int
59 devopen(f, fname, file)
60 struct open_file *f;
61 const char *fname; /* normally "1" */
62 char **file;
63 {
64 struct devsw *dp;
65 int error;
66
67 *file = (char*)fname;
68 dp = &devsw[0];
69 f->f_dev = dp;
70
71 /* The following will call tape_open() */
72 return (dp->dv_open(f, fname));
73 }
74
75 int
76 tape_open(f, fname)
77 struct open_file *f;
78 char *fname; /* partition number, i.e. "1" */
79 {
80 int part;
81 struct mvmeprom_dskio *ti;
82
83 /*
84 * Set the tape segment number to the one indicated
85 * by the single digit fname passed in above.
86 */
87 if ((fname[0] < '0') && (fname[0] > '9')) {
88 return ENOENT;
89 }
90 part = fname[0] - '0';
91
92 /*
93 * Setup our part of the saioreq.
94 * (determines what gets opened)
95 */
96 ti = &tape_ioreq;
97 bzero((caddr_t)ti, sizeof(*ti));
98
99 ti->ctrl_lun = bugargs.ctrl_lun;
100 ti->dev_lun = bugargs.dev_lun;
101 ti->status = 0;
102 ti->pbuffer = NULL;
103 ti->blk_num = part;
104 ti->blk_cnt = 0;
105 ti->flag = 0;
106 ti->addr_mod = 0;
107
108 f->f_devdata = ti;
109
110 return (0);
111 }
112
113 int
114 tape_close(f)
115 struct open_file *f;
116 {
117 struct mvmeprom_dskio *ti;
118
119
120 ti = f->f_devdata;
121 f->f_devdata = NULL;
122 return 0;
123 }
124
125 #define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE)
126
127 int
128 tape_strategy(devdata, flag, dblk, size, buf, rsize)
129 void *devdata;
130 int flag;
131 daddr_t dblk;
132 u_int size;
133 char *buf;
134 u_int *rsize;
135 {
136 struct mvmeprom_dskio *ti;
137 int ret;
138
139 ti = devdata;
140
141 if (flag != F_READ)
142 return(EROFS);
143
144 ti->status = 0;
145 ti->pbuffer = buf;
146 /* don't change block #, set in open */
147 ti->blk_cnt = size / (512 / MVMEPROM_SCALE);
148
149 /* work around for stupid '147 prom bug */
150 if ( bugargs.cputyp == 0x147 )
151 ret = hackprom_diskrd(ti);
152 else
153 ret = mvmeprom_diskrd(ti);
154
155 if (ret != 0)
156 return (EIO);
157
158 *rsize = (ti->blk_cnt / MVMEPROM_SCALE) * 512;
159 ti->flag |= IGNORE_FILENUM; /* ignore next time */
160
161 return (0);
162 }
163
164 int
165 tape_ioctl()
166 {
167 return EIO;
168 }
169
170 static int
171 hackprom_diskrd(struct mvmeprom_dskio *ti)
172 {
173 static int blkoffset = 0;
174
175 #define hackload_addr ((char *) 0x080000) /* Load tape segment here */
176 #define hackload_blocks 0x2000 /* 2Mb worth */
177
178 if ( (ti->flag & IGNORE_FILENUM) == 0 ) {
179 /*
180 * First time through. Load the whole tape segment...
181 */
182 struct mvmeprom_dskio nti;
183 int ret;
184
185 nti = *ti;
186
187 nti.pbuffer = hackload_addr;
188 nti.blk_cnt = hackload_blocks;
189 nti.flag |= END_OF_FILE;
190
191 ret = mvmeprom_diskrd(&nti);
192
193 /*
194 * PROM returns 1 on end-of-file. This isn't an
195 * error in this instance, just in case you're wondering! ;-)
196 */
197 if ( ret < 0 || ret > 1 )
198 return ret;
199
200 blkoffset = 0;
201 }
202
203 /*
204 * Grab the required number of block(s)
205 */
206 bcopy(&(hackload_addr[blkoffset]), ti->pbuffer,
207 ti->blk_cnt * MVMEPROM_BLOCK_SIZE);
208
209 blkoffset += (ti->blk_cnt * MVMEPROM_BLOCK_SIZE);
210
211 return 0;
212 }
213