bugdev.c revision 1.4 1 /* $NetBSD: bugdev.c,v 1.4 1998/08/01 11:22:52 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 #include <sys/param.h>
34 #include <sys/disklabel.h>
35 #include <machine/prom.h>
36
37 #include "stand.h"
38 #include "libsa.h"
39
40 void cputobsdlabel __P((struct disklabel *lp, struct cpu_disklabel *clp));
41
42 int errno;
43
44 struct bugsc_softc {
45 int fd; /* Prom file descriptor */
46 int poff; /* Partition offset */
47 int psize; /* Partition size */
48 short ctrl;
49 short dev;
50 } bugsc_softc[1];
51
52 int
53 devopen(f, fname, file)
54 struct open_file *f;
55 const char *fname;
56 char **file;
57 {
58 struct bugsc_softc *pp = &bugsc_softc[0];
59 int error, pn = 0;
60 char *dev, *cp;
61 size_t nrd;
62 static int iobuf[DEV_BSIZE / sizeof(int)];
63 struct disklabel sdlabel;
64
65 dev = bugargs.arg_start;
66
67 /*
68 * Extract partition # from boot device string.
69 * The Bug command line format of this is:
70 *
71 * 147-Bug> bo [drive],,[<d>:][kernel_name] [options]
72 *
73 * Where:
74 * [drive] The bug LUN number, eg. 0
75 * [<d>:] <d> is partition # ('a' to 'h')
76 * [kernel_name] Eg. netbsd or /netbsd
77 * [options] Eg. -s
78 *
79 * At this time, all we need do is scan for a ':', and assume the
80 * preceding letter is a partition id.
81 */
82 for (cp = dev + 1; *cp && cp <= bugargs.arg_end; cp++) {
83 if ( *cp == ':' ) {
84 pn = *(cp - 1) - 'a';
85 break;
86 }
87 }
88
89 if ( pn < 0 || pn >= MAXPARTITIONS ) {
90 printf("Invalid partition number; defaulting to 'a'\n");
91 pn = 0;
92 }
93
94 pp->fd = bugscopen(f);
95
96 if (pp->fd < 0) {
97 printf("Can't open device `%s'\n", dev);
98 return (ENXIO);
99 }
100 error = bugscstrategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &nrd);
101 if (error)
102 return (error);
103 if (nrd != DEV_BSIZE)
104 return (EINVAL);
105
106 /*LINTED*/
107 cputobsdlabel(&sdlabel, (struct cpu_disklabel *)&(iobuf[0]));
108 pp->poff = sdlabel.d_partitions[pn].p_offset;
109 pp->psize = sdlabel.d_partitions[pn].p_size;
110
111 f->f_dev = devsw;
112 f->f_devdata = (void *)pp;
113 /*LINTED*/
114 *file = (char *)fname;
115 return (0);
116 }
117
118 /* silly block scale factor */
119 #define BUG_BLOCK_SIZE 256
120 #define BUG_SCALE (512/BUG_BLOCK_SIZE)
121 /*ARGSUSED*/
122 int
123 bugscstrategy(devdata, func, dblk, size, buf, rsize)
124 void *devdata;
125 int func;
126 daddr_t dblk;
127 size_t size;
128 void *buf;
129 size_t *rsize;
130 {
131 struct mvmeprom_dskio dio;
132 struct bugsc_softc *pp = (struct bugsc_softc *)devdata;
133 daddr_t blk = dblk + pp->poff;
134
135 twiddle();
136
137 dio.ctrl_lun = pp->ctrl;
138 dio.dev_lun = pp->dev;
139 dio.status = 0;
140 dio.pbuffer = buf;
141 dio.blk_num = blk * BUG_SCALE;
142 dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
143 dio.flag = 0;
144 dio.addr_mod = 0;
145 #ifdef DEBUG
146 printf("bugscstrategy: size=%d blk=%d buf=%x\n", size, blk, buf);
147 printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
148 #endif
149 mvmeprom_diskrd(&dio);
150
151 *rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
152 #ifdef DEBUG
153 printf("rsize %d status %x\n", *rsize, dio.status);
154 #endif
155
156 if (dio.status)
157 return (EIO);
158 return (0);
159 }
160
161 int
162 bugscopen(f)
163 struct open_file *f;
164 {
165 #ifdef DEBUG
166 printf("bugscopen:\n");
167 #endif
168
169 f->f_devdata = (void *)bugsc_softc;
170 bugsc_softc[0].ctrl = (short)bugargs.ctrl_lun;
171 bugsc_softc[0].dev = (short)bugargs.dev_lun;
172 #ifdef DEBUG
173 printf("using mvmebug ctrl %d dev %d\n",
174 bugsc_softc[0].ctrl, bugsc_softc[0].dev);
175 #endif
176 return (0);
177 }
178
179 /*ARGSUSED*/
180 int
181 bugscclose(f)
182 struct open_file *f;
183 {
184 return (EIO);
185 }
186
187 /*ARGSUSED*/
188 int
189 bugscioctl(f, cmd, data)
190 struct open_file *f;
191 u_long cmd;
192 void *data;
193 {
194 return (EIO);
195 }
196
197 void
198 cputobsdlabel(lp, clp)
199 struct disklabel *lp;
200 struct cpu_disklabel *clp;
201 {
202 int i;
203
204 lp->d_magic = (u_int32_t)clp->magic1;
205 lp->d_type = (u_int16_t)clp->type;
206 lp->d_subtype = (u_int16_t)clp->subtype;
207
208 bcopy(clp->vid_vd, lp->d_typename, 16);
209 bcopy(clp->packname, lp->d_packname, 16);
210
211 lp->d_secsize = (u_int32_t)clp->cfg_psm;
212 lp->d_nsectors = (u_int32_t)clp->cfg_spt;
213 lp->d_ncylinders = (u_int32_t)clp->cfg_trk; /* trk is num of cyl! */
214 lp->d_ntracks = (u_int32_t)clp->cfg_hds;
215 lp->d_secpercyl = (u_int32_t)clp->secpercyl;
216 lp->d_secperunit = (u_int32_t)clp->secperunit;
217 lp->d_sparespertrack = (u_int16_t)clp->sparespertrack;
218 lp->d_sparespercyl = (u_int16_t)clp->sparespercyl;
219 lp->d_acylinders = (u_int32_t)clp->acylinders;
220 lp->d_rpm = (u_int16_t)clp->rpm;
221 lp->d_interleave = (u_int16_t)clp->cfg_ilv;
222 lp->d_trackskew = (u_int16_t)clp->cfg_sof;
223 lp->d_cylskew = (u_int16_t)clp->cylskew;
224 lp->d_headswitch = (u_int32_t)clp->headswitch;
225
226 /* this silly table is for winchester drives */
227 switch (clp->cfg_ssr) {
228 case 0:
229 lp->d_trkseek = 0;
230 break;
231 case 1:
232 lp->d_trkseek = 6;
233 break;
234 case 2:
235 lp->d_trkseek = 10;
236 break;
237 case 3:
238 lp->d_trkseek = 15;
239 break;
240 case 4:
241 lp->d_trkseek = 20;
242 break;
243 default:
244 lp->d_trkseek = 0;
245 break;
246 }
247 lp->d_flags = (u_int32_t)clp->flags;
248
249 for (i = 0; i < NDDATA; i++)
250 lp->d_drivedata[i] = (u_int32_t)clp->drivedata[i];
251
252 for (i = 0; i < NSPARE; i++)
253 lp->d_spare[i] = (u_int32_t)clp->spare[i];
254
255 lp->d_magic2 = (u_int32_t)clp->magic2;
256 lp->d_checksum = (u_int16_t)clp->checksum;
257 lp->d_npartitions = (u_int16_t)clp->partitions;
258 lp->d_bbsize = (u_int32_t)clp->bbsize;
259 lp->d_sbsize = (u_int32_t)clp->sbsize;
260
261 bcopy(clp->vid_4, &(lp->d_partitions[0]),sizeof (struct partition) * 4);
262
263 /* CONSTCOND */
264 bcopy(clp->cfg_4, &(lp->d_partitions[4]), sizeof (struct partition)
265 * ((MAXPARTITIONS < 16) ? (MAXPARTITIONS - 4) : 12));
266 }
267