1 1.54 thorpej /* $NetBSD: ofdisk.c,v 1.54 2020/01/26 21:43:52 thorpej Exp $ */ 2 1.1 ws 3 1.1 ws /* 4 1.1 ws * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 1.1 ws * Copyright (C) 1995, 1996 TooLs GmbH. 6 1.1 ws * All rights reserved. 7 1.1 ws * 8 1.1 ws * Redistribution and use in source and binary forms, with or without 9 1.1 ws * modification, are permitted provided that the following conditions 10 1.1 ws * are met: 11 1.1 ws * 1. Redistributions of source code must retain the above copyright 12 1.1 ws * notice, this list of conditions and the following disclaimer. 13 1.1 ws * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 ws * notice, this list of conditions and the following disclaimer in the 15 1.1 ws * documentation and/or other materials provided with the distribution. 16 1.1 ws * 3. All advertising materials mentioning features or use of this software 17 1.1 ws * must display the following acknowledgement: 18 1.1 ws * This product includes software developed by TooLs GmbH. 19 1.1 ws * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 1.1 ws * derived from this software without specific prior written permission. 21 1.1 ws * 22 1.1 ws * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 1.1 ws * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 ws * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 ws * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 1.1 ws * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 1.1 ws * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 1.1 ws * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 ws * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 1.1 ws * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 1.1 ws * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 ws */ 33 1.18 lukem 34 1.18 lukem #include <sys/cdefs.h> 35 1.54 thorpej __KERNEL_RCSID(0, "$NetBSD: ofdisk.c,v 1.54 2020/01/26 21:43:52 thorpej Exp $"); 36 1.1 ws 37 1.1 ws #include <sys/param.h> 38 1.1 ws #include <sys/buf.h> 39 1.1 ws #include <sys/device.h> 40 1.16 matt #include <sys/conf.h> 41 1.1 ws #include <sys/disklabel.h> 42 1.1 ws #include <sys/disk.h> 43 1.1 ws #include <sys/fcntl.h> 44 1.1 ws #include <sys/ioctl.h> 45 1.1 ws #include <sys/stat.h> 46 1.1 ws #include <sys/systm.h> 47 1.6 thorpej #include <sys/proc.h> 48 1.1 ws 49 1.1 ws #include <dev/ofw/openfirm.h> 50 1.1 ws 51 1.10 mycroft struct ofdisk_softc { 52 1.44 mrg device_t sc_dev; 53 1.1 ws int sc_phandle; 54 1.1 ws int sc_unit; 55 1.4 thorpej int sc_flags; 56 1.1 ws struct disk sc_dk; 57 1.1 ws int sc_ihandle; 58 1.1 ws u_long max_transfer; 59 1.1 ws }; 60 1.1 ws 61 1.4 thorpej /* sc_flags */ 62 1.4 thorpej #define OFDF_ISFLOPPY 0x01 /* we are a floppy drive */ 63 1.4 thorpej 64 1.29 thorpej #define OFDISK_FLOPPY_P(of) ((of)->sc_flags & OFDF_ISFLOPPY) 65 1.29 thorpej 66 1.43 cegger static int ofdisk_match (device_t, cfdata_t, void *); 67 1.43 cegger static void ofdisk_attach (device_t, device_t, void *); 68 1.1 ws 69 1.44 mrg CFATTACH_DECL_NEW(ofdisk, sizeof(struct ofdisk_softc), 70 1.23 thorpej ofdisk_match, ofdisk_attach, NULL, NULL); 71 1.1 ws 72 1.9 thorpej extern struct cfdriver ofdisk_cd; 73 1.1 ws 74 1.19 gehenna dev_type_open(ofdisk_open); 75 1.19 gehenna dev_type_close(ofdisk_close); 76 1.19 gehenna dev_type_read(ofdisk_read); 77 1.19 gehenna dev_type_write(ofdisk_write); 78 1.19 gehenna dev_type_ioctl(ofdisk_ioctl); 79 1.19 gehenna dev_type_strategy(ofdisk_strategy); 80 1.19 gehenna dev_type_dump(ofdisk_dump); 81 1.19 gehenna dev_type_size(ofdisk_size); 82 1.19 gehenna 83 1.19 gehenna const struct bdevsw ofdisk_bdevsw = { 84 1.45 dholland .d_open = ofdisk_open, 85 1.45 dholland .d_close = ofdisk_close, 86 1.45 dholland .d_strategy = ofdisk_strategy, 87 1.45 dholland .d_ioctl = ofdisk_ioctl, 88 1.45 dholland .d_dump = ofdisk_dump, 89 1.45 dholland .d_psize = ofdisk_size, 90 1.46 dholland .d_discard = nodiscard, 91 1.45 dholland .d_flag = D_DISK 92 1.19 gehenna }; 93 1.19 gehenna 94 1.19 gehenna const struct cdevsw ofdisk_cdevsw = { 95 1.45 dholland .d_open = ofdisk_open, 96 1.45 dholland .d_close = ofdisk_close, 97 1.45 dholland .d_read = ofdisk_read, 98 1.45 dholland .d_write = ofdisk_write, 99 1.45 dholland .d_ioctl = ofdisk_ioctl, 100 1.45 dholland .d_stop = nostop, 101 1.45 dholland .d_tty = notty, 102 1.45 dholland .d_poll = nopoll, 103 1.45 dholland .d_mmap = nommap, 104 1.45 dholland .d_kqfilter = nokqfilter, 105 1.47 dholland .d_discard = nodiscard, 106 1.45 dholland .d_flag = D_DISK 107 1.19 gehenna }; 108 1.1 ws 109 1.29 thorpej static void ofminphys(struct buf *); 110 1.29 thorpej 111 1.51 mlelstv struct dkdriver ofdisk_dkdriver = { 112 1.51 mlelstv .d_strategy = ofdisk_strategy, 113 1.51 mlelstv .d_minphys = ofminphys 114 1.51 mlelstv }; 115 1.1 ws 116 1.17 matt void ofdisk_getdefaultlabel (struct ofdisk_softc *, struct disklabel *); 117 1.17 matt void ofdisk_getdisklabel (dev_t); 118 1.7 thorpej 119 1.1 ws static int 120 1.43 cegger ofdisk_match(device_t parent, cfdata_t match, void *aux) 121 1.1 ws { 122 1.10 mycroft struct ofbus_attach_args *oba = aux; 123 1.1 ws char type[8]; 124 1.1 ws int l; 125 1.30 perry 126 1.10 mycroft if (strcmp(oba->oba_busname, "ofw")) 127 1.10 mycroft return (0); 128 1.10 mycroft if ((l = OF_getprop(oba->oba_phandle, "device_type", type, 129 1.4 thorpej sizeof type - 1)) < 0) 130 1.1 ws return 0; 131 1.1 ws if (l >= sizeof type) 132 1.1 ws return 0; 133 1.1 ws type[l] = 0; 134 1.52 martin return strcmp(type, "block") == 0 || strcmp(type, "scsi") == 0; 135 1.1 ws } 136 1.1 ws 137 1.1 ws static void 138 1.43 cegger ofdisk_attach(device_t parent, device_t self, void *aux) 139 1.1 ws { 140 1.33 thorpej struct ofdisk_softc *of = device_private(self); 141 1.10 mycroft struct ofbus_attach_args *oba = aux; 142 1.4 thorpej char child[64]; 143 1.1 ws int l; 144 1.4 thorpej 145 1.44 mrg of->sc_dev = self; 146 1.10 mycroft if ((l = OF_getprop(oba->oba_phandle, "name", child, 147 1.4 thorpej sizeof child - 1)) < 0) 148 1.4 thorpej panic("device without name?"); 149 1.4 thorpej if (l >= sizeof child) 150 1.4 thorpej l = sizeof child - 1; 151 1.4 thorpej child[l] = 0; 152 1.4 thorpej 153 1.4 thorpej of->sc_flags = 0; 154 1.10 mycroft of->sc_phandle = oba->oba_phandle; 155 1.10 mycroft of->sc_unit = oba->oba_unit; 156 1.1 ws of->sc_ihandle = 0; 157 1.44 mrg disk_init(&of->sc_dk, device_xname(of->sc_dev), &ofdisk_dkdriver); 158 1.1 ws disk_attach(&of->sc_dk); 159 1.3 christos printf("\n"); 160 1.4 thorpej 161 1.4 thorpej if (strcmp(child, "floppy") == 0) 162 1.4 thorpej of->sc_flags |= OFDF_ISFLOPPY; 163 1.29 thorpej else { 164 1.29 thorpej /* Discover wedges on this disk. */ 165 1.29 thorpej dkwedge_discover(&of->sc_dk); 166 1.29 thorpej } 167 1.1 ws } 168 1.1 ws 169 1.1 ws int 170 1.32 christos ofdisk_open(dev_t dev, int flags, int fmt, struct lwp *lwp) 171 1.1 ws { 172 1.10 mycroft struct ofdisk_softc *of; 173 1.1 ws char path[256]; 174 1.29 thorpej int error, l, part; 175 1.30 perry 176 1.41 cegger of = device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); 177 1.41 cegger if (of == NULL) 178 1.1 ws return ENXIO; 179 1.1 ws 180 1.29 thorpej part = DISKPART(dev); 181 1.29 thorpej 182 1.36 ad mutex_enter(&of->sc_dk.dk_openlock); 183 1.29 thorpej 184 1.29 thorpej /* 185 1.29 thorpej * If there are wedges, and this is not RAW_PART, then we 186 1.29 thorpej * need to fail. 187 1.29 thorpej */ 188 1.29 thorpej if (of->sc_dk.dk_nwedges != 0 && part != RAW_PART) { 189 1.29 thorpej error = EBUSY; 190 1.29 thorpej goto bad1; 191 1.29 thorpej } 192 1.29 thorpej 193 1.1 ws if (!of->sc_ihandle) { 194 1.4 thorpej if ((l = OF_package_to_path(of->sc_phandle, path, 195 1.11 mycroft sizeof path - 3)) < 0 || 196 1.29 thorpej l >= sizeof path - 3) { 197 1.29 thorpej error = ENXIO; 198 1.29 thorpej goto bad1; 199 1.29 thorpej } 200 1.1 ws path[l] = 0; 201 1.1 ws 202 1.1 ws /* 203 1.4 thorpej * XXX This is for the benefit of SCSI/IDE disks that don't 204 1.4 thorpej * XXX have all their childs in the device tree. 205 1.4 thorpej * XXX YES, I DO THINK THIS IS A BUG IN OPENFIRMWARE!!! 206 1.4 thorpej * XXX And yes, this is a very gross hack! 207 1.4 thorpej * XXX See also ofscsi.c 208 1.1 ws */ 209 1.1 ws if (!strcmp(path + l - 4, "disk")) { 210 1.1 ws path[l++] = '@'; 211 1.1 ws path[l++] = '0' + of->sc_unit; 212 1.1 ws path[l] = 0; 213 1.1 ws } 214 1.1 ws 215 1.28 itojun strlcat(path, ":0", sizeof(path)); 216 1.1 ws 217 1.29 thorpej if ((of->sc_ihandle = OF_open(path)) == -1) { 218 1.29 thorpej error = ENXIO; 219 1.29 thorpej goto bad1; 220 1.29 thorpej } 221 1.1 ws 222 1.1 ws /* 223 1.1 ws * Try to get characteristics of the disk. 224 1.1 ws */ 225 1.4 thorpej of->max_transfer = OF_call_method_1("max-transfer", 226 1.4 thorpej of->sc_ihandle, 0); 227 1.1 ws if (of->max_transfer > MAXPHYS) 228 1.1 ws of->max_transfer = MAXPHYS; 229 1.4 thorpej 230 1.10 mycroft ofdisk_getdisklabel(dev); 231 1.1 ws } 232 1.1 ws 233 1.1 ws switch (fmt) { 234 1.1 ws case S_IFCHR: 235 1.29 thorpej of->sc_dk.dk_copenmask |= 1 << part; 236 1.1 ws break; 237 1.1 ws case S_IFBLK: 238 1.29 thorpej of->sc_dk.dk_bopenmask |= 1 << part; 239 1.1 ws break; 240 1.1 ws } 241 1.4 thorpej of->sc_dk.dk_openmask = 242 1.4 thorpej of->sc_dk.dk_copenmask | of->sc_dk.dk_bopenmask; 243 1.29 thorpej 244 1.29 thorpej 245 1.36 ad error = 0; 246 1.29 thorpej bad1: 247 1.36 ad mutex_exit(&of->sc_dk.dk_openlock); 248 1.29 thorpej return (error); 249 1.1 ws } 250 1.1 ws 251 1.1 ws int 252 1.32 christos ofdisk_close(dev_t dev, int flags, int fmt, struct lwp *l) 253 1.1 ws { 254 1.41 cegger struct ofdisk_softc *of = 255 1.41 cegger device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); 256 1.29 thorpej 257 1.36 ad mutex_enter(&of->sc_dk.dk_openlock); 258 1.1 ws 259 1.1 ws switch (fmt) { 260 1.1 ws case S_IFCHR: 261 1.1 ws of->sc_dk.dk_copenmask &= ~(1 << DISKPART(dev)); 262 1.1 ws break; 263 1.1 ws case S_IFBLK: 264 1.1 ws of->sc_dk.dk_bopenmask &= ~(1 << DISKPART(dev)); 265 1.1 ws break; 266 1.1 ws } 267 1.1 ws of->sc_dk.dk_openmask = of->sc_dk.dk_copenmask | of->sc_dk.dk_bopenmask; 268 1.30 perry 269 1.4 thorpej #ifdef FIRMWORKSBUGS 270 1.1 ws /* 271 1.1 ws * This is a hack to get the firmware to flush its buffers. 272 1.1 ws */ 273 1.1 ws OF_seek(of->sc_ihandle, 0); 274 1.1 ws #endif 275 1.1 ws if (!of->sc_dk.dk_openmask) { 276 1.1 ws OF_close(of->sc_ihandle); 277 1.1 ws of->sc_ihandle = 0; 278 1.1 ws } 279 1.1 ws 280 1.36 ad mutex_exit(&of->sc_dk.dk_openlock); 281 1.1 ws return 0; 282 1.1 ws } 283 1.1 ws 284 1.1 ws void 285 1.17 matt ofdisk_strategy(struct buf *bp) 286 1.1 ws { 287 1.41 cegger struct ofdisk_softc *of = 288 1.41 cegger device_lookup_private(&ofdisk_cd, DISKUNIT(bp->b_dev)); 289 1.1 ws struct partition *p; 290 1.1 ws u_quad_t off; 291 1.1 ws int read; 292 1.1 ws int (*OF_io)(int, void *, int); 293 1.1 ws daddr_t blkno = bp->b_blkno; 294 1.4 thorpej 295 1.1 ws bp->b_resid = 0; 296 1.1 ws if (bp->b_bcount == 0) 297 1.1 ws goto done; 298 1.30 perry 299 1.31 he OF_io = bp->b_flags & B_READ ? OF_read : 300 1.31 he (int(*)(int, void*, int))OF_write; 301 1.1 ws 302 1.1 ws if (DISKPART(bp->b_dev) != RAW_PART) { 303 1.27 thorpej if (bounds_check_with_label(&of->sc_dk, bp, 0) <= 0) { 304 1.1 ws bp->b_resid = bp->b_bcount; 305 1.1 ws goto done; 306 1.1 ws } 307 1.1 ws p = &of->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)]; 308 1.1 ws blkno = bp->b_blkno + p->p_offset; 309 1.1 ws } 310 1.4 thorpej 311 1.1 ws disk_busy(&of->sc_dk); 312 1.1 ws 313 1.1 ws off = (u_quad_t)blkno * DEV_BSIZE; 314 1.1 ws read = -1; 315 1.1 ws do { 316 1.1 ws if (OF_seek(of->sc_ihandle, off) < 0) 317 1.1 ws break; 318 1.1 ws read = OF_io(of->sc_ihandle, bp->b_data, bp->b_bcount); 319 1.1 ws } while (read == -2); 320 1.4 thorpej 321 1.1 ws if (read < 0) { 322 1.1 ws bp->b_error = EIO; 323 1.1 ws bp->b_resid = bp->b_bcount; 324 1.1 ws } else 325 1.1 ws bp->b_resid = bp->b_bcount - read; 326 1.1 ws 327 1.25 mrg disk_unbusy(&of->sc_dk, bp->b_bcount - bp->b_resid, 328 1.25 mrg (bp->b_flags & B_READ)); 329 1.1 ws 330 1.1 ws done: 331 1.1 ws biodone(bp); 332 1.1 ws } 333 1.1 ws 334 1.1 ws static void 335 1.17 matt ofminphys(struct buf *bp) 336 1.1 ws { 337 1.41 cegger struct ofdisk_softc *of = 338 1.41 cegger device_lookup_private(&ofdisk_cd, DISKUNIT(bp->b_dev)); 339 1.30 perry 340 1.1 ws if (bp->b_bcount > of->max_transfer) 341 1.1 ws bp->b_bcount = of->max_transfer; 342 1.1 ws } 343 1.1 ws 344 1.1 ws int 345 1.17 matt ofdisk_read(dev_t dev, struct uio *uio, int flags) 346 1.1 ws { 347 1.10 mycroft return physio(ofdisk_strategy, NULL, dev, B_READ, ofminphys, uio); 348 1.1 ws } 349 1.1 ws 350 1.1 ws int 351 1.17 matt ofdisk_write(dev_t dev, struct uio *uio, int flags) 352 1.1 ws { 353 1.10 mycroft return physio(ofdisk_strategy, NULL, dev, B_WRITE, ofminphys, uio); 354 1.1 ws } 355 1.1 ws 356 1.1 ws int 357 1.35 christos ofdisk_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 358 1.1 ws { 359 1.41 cegger struct ofdisk_softc *of = 360 1.41 cegger device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); 361 1.1 ws int error; 362 1.14 fvdl #ifdef __HAVE_OLD_DISKLABEL 363 1.14 fvdl struct disklabel newlabel; 364 1.14 fvdl #endif 365 1.49 christos /* XXX: Why not allow wedges on floppy? */ 366 1.49 christos switch (cmd) { 367 1.49 christos case DIOCDWEDGE: 368 1.49 christos case DIOCAWEDGE: 369 1.49 christos case DIOCLWEDGES: 370 1.53 martin case DIOCRMWEDGES: 371 1.49 christos case DIOCMWEDGES: 372 1.49 christos if (OFDISK_FLOPPY_P(of)) 373 1.49 christos return ENOTTY; 374 1.49 christos } 375 1.49 christos 376 1.50 christos error = disk_ioctl(&of->sc_dk, dev, cmd, data, flag, l); 377 1.49 christos if (error != EPASSTHROUGH) 378 1.49 christos return error; 379 1.30 perry 380 1.1 ws switch (cmd) { 381 1.1 ws case DIOCWDINFO: 382 1.1 ws case DIOCSDINFO: 383 1.14 fvdl #ifdef __HAVE_OLD_DISKLABEL 384 1.14 fvdl case ODIOCWDINFO: 385 1.14 fvdl case ODIOCSDINFO: 386 1.14 fvdl #endif 387 1.14 fvdl { 388 1.14 fvdl struct disklabel *lp; 389 1.14 fvdl 390 1.14 fvdl #ifdef __HAVE_OLD_DISKLABEL 391 1.14 fvdl if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) { 392 1.14 fvdl memset(&newlabel, 0, sizeof newlabel); 393 1.14 fvdl memcpy(&newlabel, data, sizeof (struct olddisklabel)); 394 1.14 fvdl lp = &newlabel; 395 1.14 fvdl } else 396 1.14 fvdl #endif 397 1.14 fvdl lp = (struct disklabel *)data; 398 1.14 fvdl 399 1.1 ws if ((flag & FWRITE) == 0) 400 1.1 ws return EBADF; 401 1.29 thorpej 402 1.36 ad mutex_enter(&of->sc_dk.dk_openlock); 403 1.29 thorpej 404 1.1 ws error = setdisklabel(of->sc_dk.dk_label, 405 1.14 fvdl lp, /*of->sc_dk.dk_openmask */0, 406 1.4 thorpej of->sc_dk.dk_cpulabel); 407 1.54 thorpej if (error == 0 && (cmd == DIOCWDINFO 408 1.14 fvdl #ifdef __HAVE_OLD_DISKLABEL 409 1.54 thorpej || cmd == ODIOCWDINFO 410 1.14 fvdl #endif 411 1.54 thorpej )) 412 1.1 ws error = writedisklabel(MAKEDISKDEV(major(dev), 413 1.10 mycroft DISKUNIT(dev), RAW_PART), ofdisk_strategy, 414 1.4 thorpej of->sc_dk.dk_label, of->sc_dk.dk_cpulabel); 415 1.1 ws 416 1.36 ad mutex_exit(&of->sc_dk.dk_openlock); 417 1.29 thorpej 418 1.1 ws return error; 419 1.14 fvdl } 420 1.7 thorpej 421 1.7 thorpej case DIOCGDEFLABEL: 422 1.10 mycroft ofdisk_getdefaultlabel(of, (struct disklabel *)data); 423 1.7 thorpej return 0; 424 1.14 fvdl #ifdef __HAVE_OLD_DISKLABEL 425 1.54 thorpej case ODIOCGDEFLABEL: 426 1.14 fvdl ofdisk_getdefaultlabel(of, &newlabel); 427 1.14 fvdl if (newlabel.d_npartitions > OLDMAXPARTITIONS) 428 1.15 fvdl return ENOTTY; 429 1.14 fvdl memcpy(data, &newlabel, sizeof (struct olddisklabel)); 430 1.14 fvdl return 0; 431 1.14 fvdl #endif 432 1.7 thorpej 433 1.1 ws default: 434 1.1 ws return ENOTTY; 435 1.1 ws } 436 1.1 ws } 437 1.1 ws 438 1.1 ws int 439 1.35 christos ofdisk_dump(dev_t dev, daddr_t blkno, void *va, size_t size) 440 1.1 ws { 441 1.1 ws return EINVAL; 442 1.1 ws } 443 1.1 ws 444 1.1 ws int 445 1.17 matt ofdisk_size(dev_t dev) 446 1.1 ws { 447 1.10 mycroft struct ofdisk_softc *of; 448 1.5 thorpej struct disklabel *lp; 449 1.41 cegger int size, part, omask; 450 1.5 thorpej 451 1.41 cegger of = device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); 452 1.41 cegger if (of == NULL) 453 1.41 cegger return ENXIO; 454 1.5 thorpej 455 1.1 ws part = DISKPART(dev); 456 1.5 thorpej omask = of->sc_dk.dk_openmask & (1 << part); 457 1.6 thorpej lp = of->sc_dk.dk_label; 458 1.5 thorpej 459 1.32 christos if (omask == 0 && ofdisk_open(dev, 0, S_IFBLK, curlwp) != 0) 460 1.5 thorpej return -1; 461 1.5 thorpej 462 1.5 thorpej if (lp->d_partitions[part].p_fstype != FS_SWAP) 463 1.1 ws size = -1; 464 1.1 ws else 465 1.5 thorpej size = lp->d_partitions[part].p_size * 466 1.5 thorpej (lp->d_secsize / DEV_BSIZE); 467 1.5 thorpej 468 1.32 christos if (omask == 0 && ofdisk_close(dev, 0, S_IFBLK, curlwp) != 0) 469 1.1 ws return -1; 470 1.5 thorpej 471 1.1 ws return size; 472 1.7 thorpej } 473 1.7 thorpej 474 1.7 thorpej void 475 1.17 matt ofdisk_getdefaultlabel(struct ofdisk_softc *of, struct disklabel *lp) 476 1.7 thorpej { 477 1.7 thorpej 478 1.17 matt memset(lp, 0, sizeof *lp); 479 1.7 thorpej 480 1.7 thorpej /* 481 1.7 thorpej * XXX Firmware bug? Asking for block size gives a 482 1.20 chs * XXX ridiculous number! So we use what the boot program 483 1.7 thorpej * XXX uses. 484 1.7 thorpej */ 485 1.7 thorpej lp->d_secsize = DEV_BSIZE; 486 1.7 thorpej 487 1.7 thorpej lp->d_secperunit = OF_call_method_1("#blocks", 488 1.7 thorpej of->sc_ihandle, 0); 489 1.7 thorpej if (lp->d_secperunit == (u_int32_t)-1) 490 1.7 thorpej lp->d_secperunit = 0x7fffffff; 491 1.7 thorpej 492 1.7 thorpej lp->d_secpercyl = 1; 493 1.7 thorpej lp->d_nsectors = 1; 494 1.7 thorpej lp->d_ntracks = 1; 495 1.7 thorpej lp->d_ncylinders = lp->d_secperunit; 496 1.7 thorpej 497 1.7 thorpej lp->d_partitions[RAW_PART].p_offset = 0; 498 1.7 thorpej lp->d_partitions[RAW_PART].p_size = lp->d_secperunit; 499 1.7 thorpej lp->d_npartitions = RAW_PART + 1; 500 1.7 thorpej 501 1.7 thorpej lp->d_magic = DISKMAGIC; 502 1.7 thorpej lp->d_magic2 = DISKMAGIC; 503 1.7 thorpej lp->d_checksum = dkcksum(lp); 504 1.7 thorpej } 505 1.7 thorpej 506 1.7 thorpej void 507 1.41 cegger ofdisk_getdisklabel(dev_t dev) 508 1.7 thorpej { 509 1.7 thorpej int unit = DISKUNIT(dev); 510 1.41 cegger struct ofdisk_softc *of = 511 1.41 cegger device_lookup_private(&ofdisk_cd, unit); 512 1.7 thorpej struct disklabel *lp = of->sc_dk.dk_label; 513 1.26 dsl const char *errmes; 514 1.7 thorpej int l; 515 1.7 thorpej 516 1.10 mycroft ofdisk_getdefaultlabel(of, lp); 517 1.7 thorpej 518 1.7 thorpej /* 519 1.7 thorpej * Don't read the disklabel on a floppy; simply 520 1.7 thorpej * assign all partitions the same size/offset as 521 1.7 thorpej * RAW_PART. (This is essentially what the ISA 522 1.7 thorpej * floppy driver does, but we don't deal with 523 1.7 thorpej * density stuff.) 524 1.7 thorpej */ 525 1.29 thorpej if (OFDISK_FLOPPY_P(of)) { 526 1.7 thorpej lp->d_npartitions = MAXPARTITIONS; 527 1.7 thorpej for (l = 0; l < lp->d_npartitions; l++) { 528 1.7 thorpej if (l == RAW_PART) 529 1.7 thorpej continue; 530 1.7 thorpej /* struct copy */ 531 1.7 thorpej lp->d_partitions[l] = 532 1.7 thorpej lp->d_partitions[RAW_PART]; 533 1.7 thorpej } 534 1.7 thorpej lp->d_checksum = dkcksum(lp); 535 1.7 thorpej } else { 536 1.7 thorpej errmes = readdisklabel(MAKEDISKDEV(major(dev), 537 1.10 mycroft unit, RAW_PART), ofdisk_strategy, lp, 538 1.7 thorpej of->sc_dk.dk_cpulabel); 539 1.7 thorpej if (errmes != NULL) 540 1.44 mrg printf("%s: %s\n", device_xname(of->sc_dev), errmes); 541 1.7 thorpej } 542 1.1 ws } 543