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