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