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