bugdev.c revision 1.6 1 /* $NetBSD: bugdev.c,v 1.6 2001/07/07 09:06:44 scw Exp $ */
2
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Paul Kranenburg.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/param.h>
40 #include <sys/disklabel.h>
41 #include <machine/prom.h>
42
43 #include "stand.h"
44 #include "libsa.h"
45
46 void cputobsdlabel __P((struct disklabel *lp, struct cpu_disklabel *clp));
47
48 int errno;
49
50 struct bugsc_softc {
51 int fd; /* Prom file descriptor */
52 int poff; /* Partition offset */
53 int psize; /* Partition size */
54 short ctrl;
55 short dev;
56 } bugsc_softc[1];
57
58 int
59 devopen(f, fname, file)
60 struct open_file *f;
61 const char *fname;
62 char **file;
63 {
64 struct bugsc_softc *pp = &bugsc_softc[0];
65 int error, pn = 0;
66 char *dev, *cp;
67 size_t nrd;
68 static int iobuf[DEV_BSIZE / sizeof(int)];
69 struct disklabel sdlabel;
70
71 dev = bugargs.arg_start;
72
73 /*
74 * Extract partition # from boot device string.
75 * The Bug command line format of this is:
76 *
77 * 147-Bug> bo [drive],,[<d>:][kernel_name] [options]
78 *
79 * Where:
80 * [drive] The bug LUN number, eg. 0
81 * [<d>:] <d> is partition # ('a' to 'h')
82 * [kernel_name] Eg. netbsd or /netbsd
83 * [options] Eg. -s
84 *
85 * At this time, all we need do is scan for a ':', and assume the
86 * preceding letter is a partition id.
87 */
88 for (cp = dev + 1; *cp && cp <= bugargs.arg_end; cp++) {
89 if ( *cp == ':' ) {
90 pn = *(cp - 1) - 'a';
91 break;
92 }
93 }
94
95 if ( pn < 0 || pn >= MAXPARTITIONS ) {
96 printf("Invalid partition number; defaulting to 'a'\n");
97 pn = 0;
98 }
99
100 pp->fd = bugscopen(f);
101
102 if (pp->fd < 0) {
103 printf("Can't open device `%s'\n", dev);
104 return (ENXIO);
105 }
106 error = bugscstrategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &nrd);
107 if (error)
108 return (error);
109 if (nrd != DEV_BSIZE)
110 return (EINVAL);
111
112 /*LINTED*/
113 cputobsdlabel(&sdlabel, (struct cpu_disklabel *)&(iobuf[0]));
114 pp->poff = sdlabel.d_partitions[pn].p_offset;
115 pp->psize = sdlabel.d_partitions[pn].p_size;
116
117 f->f_dev = devsw;
118 f->f_devdata = (void *)pp;
119 /*LINTED*/
120 *file = (char *)fname;
121 return (0);
122 }
123
124 /* silly block scale factor */
125 #define BUG_BLOCK_SIZE 256
126 #define BUG_SCALE (512/BUG_BLOCK_SIZE)
127 /*ARGSUSED*/
128 int
129 bugscstrategy(devdata, func, dblk, size, buf, rsize)
130 void *devdata;
131 int func;
132 daddr_t dblk;
133 size_t size;
134 void *buf;
135 size_t *rsize;
136 {
137 struct mvmeprom_dskio dio;
138 struct bugsc_softc *pp = (struct bugsc_softc *)devdata;
139 daddr_t blk = dblk + pp->poff;
140
141 twiddle();
142
143 dio.ctrl_lun = pp->ctrl;
144 dio.dev_lun = pp->dev;
145 dio.status = 0;
146 dio.pbuffer = buf;
147 dio.blk_num = blk * BUG_SCALE;
148 dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
149 dio.flag = 0;
150 dio.addr_mod = 0;
151 #ifdef DEBUG
152 printf("bugscstrategy: size=%d blk=%d buf=%x\n", size, blk, buf);
153 printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
154 #endif
155 mvmeprom_diskrd(&dio);
156
157 *rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
158 #ifdef DEBUG
159 printf("rsize %d status %x\n", *rsize, dio.status);
160 #endif
161
162 if (dio.status)
163 return (EIO);
164 return (0);
165 }
166
167 int
168 bugscopen(f)
169 struct open_file *f;
170 {
171 #ifdef DEBUG
172 printf("bugscopen:\n");
173 #endif
174
175 f->f_devdata = (void *)bugsc_softc;
176 bugsc_softc[0].ctrl = (short)bugargs.ctrl_lun;
177 bugsc_softc[0].dev = (short)bugargs.dev_lun;
178 #ifdef DEBUG
179 printf("using mvmebug ctrl %d dev %d\n",
180 bugsc_softc[0].ctrl, bugsc_softc[0].dev);
181 #endif
182 return (0);
183 }
184
185 /*ARGSUSED*/
186 int
187 bugscclose(f)
188 struct open_file *f;
189 {
190 return (EIO);
191 }
192
193 /*ARGSUSED*/
194 int
195 bugscioctl(f, cmd, data)
196 struct open_file *f;
197 u_long cmd;
198 void *data;
199 {
200 return (EIO);
201 }
202
203 void
204 cputobsdlabel(lp, clp)
205 struct disklabel *lp;
206 struct cpu_disklabel *clp;
207 {
208 int i;
209
210 lp->d_magic = (u_int32_t)clp->magic1;
211 lp->d_type = (u_int16_t)clp->type;
212 lp->d_subtype = (u_int16_t)clp->subtype;
213
214 memcpy(lp->d_typename, clp->vid_vd, 16);
215 memcpy(lp->d_packname, clp->packname, 16);
216
217 lp->d_secsize = (u_int32_t)clp->cfg_psm;
218 lp->d_nsectors = (u_int32_t)clp->cfg_spt;
219 lp->d_ncylinders = (u_int32_t)clp->cfg_trk; /* trk is num of cyl! */
220 lp->d_ntracks = (u_int32_t)clp->cfg_hds;
221 lp->d_secpercyl = (u_int32_t)clp->secpercyl;
222 lp->d_secperunit = (u_int32_t)clp->secperunit;
223 lp->d_sparespertrack = (u_int16_t)clp->sparespertrack;
224 lp->d_sparespercyl = (u_int16_t)clp->sparespercyl;
225 lp->d_acylinders = (u_int32_t)clp->acylinders;
226 lp->d_rpm = (u_int16_t)clp->rpm;
227 lp->d_interleave = (u_int16_t)clp->cfg_ilv;
228 lp->d_trackskew = (u_int16_t)clp->cfg_sof;
229 lp->d_cylskew = (u_int16_t)clp->cylskew;
230 lp->d_headswitch = (u_int32_t)clp->headswitch;
231
232 /* this silly table is for winchester drives */
233 switch (clp->cfg_ssr) {
234 case 0:
235 lp->d_trkseek = 0;
236 break;
237 case 1:
238 lp->d_trkseek = 6;
239 break;
240 case 2:
241 lp->d_trkseek = 10;
242 break;
243 case 3:
244 lp->d_trkseek = 15;
245 break;
246 case 4:
247 lp->d_trkseek = 20;
248 break;
249 default:
250 lp->d_trkseek = 0;
251 break;
252 }
253 lp->d_flags = (u_int32_t)clp->flags;
254
255 for (i = 0; i < NDDATA; i++)
256 lp->d_drivedata[i] = (u_int32_t)clp->drivedata[i];
257
258 for (i = 0; i < NSPARE; i++)
259 lp->d_spare[i] = (u_int32_t)clp->spare[i];
260
261 lp->d_magic2 = (u_int32_t)clp->magic2;
262 lp->d_checksum = (u_int16_t)clp->checksum;
263 lp->d_npartitions = (u_int16_t)clp->partitions;
264 lp->d_bbsize = (u_int32_t)clp->bbsize;
265 lp->d_sbsize = (u_int32_t)clp->sbsize;
266
267 memcpy(&(lp->d_partitions[0]), clp->vid_4,
268 sizeof (struct partition) * 4);
269
270 /* CONSTCOND */
271 memcpy(&(lp->d_partitions[4]), clp->cfg_4, sizeof (struct partition)
272 * ((MAXPARTITIONS < 16) ? (MAXPARTITIONS - 4) : 12));
273 }
274