Annotation of sys/arch/mvmeppc/stand/libsa/bugdev.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: bugdev.c,v 1.4 2006/10/12 12:14:17 krw 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 <ufs.h>
! 39: #include "rawfs.h"
! 40: #include "tftpfs.h"
! 41:
! 42: #include "libsa.h"
! 43:
! 44: int errno;
! 45: int bootdev_type = BUGDEV_DISK;
! 46:
! 47: #if 1
! 48: #define md_swap_long(x) ( (((x) >> 24) & 0xff) | (((x) >> 8 ) & 0xff00) | \
! 49: (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000))
! 50: #else
! 51: #define md_swap_long(x) (x)
! 52: #endif
! 53:
! 54: struct bugdev_softc {
! 55: int fd; /* Prom file descriptor */
! 56: u_int pnum; /* Partition number */
! 57: u_int poff; /* Partition offset */
! 58: u_int psize; /* Partition size */
! 59: short clun;
! 60: short dlun;
! 61: } bugdev_softc[1];
! 62:
! 63: extern struct fs_ops ufs_file_system;
! 64: extern struct fs_ops tftp_file_system;
! 65: extern struct fs_ops raw_file_system;
! 66:
! 67: struct fs_ops file_system[1];
! 68:
! 69: struct mvmeprom_dskio tape_ioreq;
! 70:
! 71: #ifdef BUG_DEBUG
! 72: unsigned io = 0, mem = 0;
! 73: #define PCI_BASE 0x80000000
! 74: #define CFC *(unsigned *)(PCI_BASE + 0xcfc)
! 75: #define CF8 *(unsigned *)(PCI_BASE + 0xcf8)
! 76: #define BUS_SHIFT 16
! 77: #define DEVICE_SHIFT 11
! 78: #define FNC_SHIFT 8
! 79:
! 80: unsigned
! 81: bugpci_make_tag(bus, dev, fnc)
! 82: int bus, dev, fnc;
! 83: {
! 84: return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT);
! 85: }
! 86:
! 87: static unsigned
! 88: bugpci_gen_config_reg(tag, offset)
! 89: unsigned tag;
! 90: int offset;
! 91: {
! 92: unsigned reg;
! 93:
! 94: /* config mechanism #2, type 0
! 95: /* standard cf8/cfc config */
! 96: reg = 0x80000000 | tag | offset;
! 97:
! 98: return reg;
! 99: }
! 100:
! 101: /*#define DEBUG_CONFIG */
! 102: unsigned
! 103: bugpci_conf_read(bus, dev, func, offset)
! 104: int bus, dev, func, offset;
! 105: {
! 106:
! 107: unsigned data;
! 108: unsigned reg, tag, xx;
! 109:
! 110: if(offset & 3 || offset < 0 || offset >= 0x100) {
! 111: printf ("bugpci_conf_read: bad reg %x\n", offset);
! 112: return(~0);
! 113: }
! 114:
! 115: tag = bugpci_make_tag(bus, dev, func);
! 116: reg = bugpci_gen_config_reg(tag, offset);
! 117: reg = md_swap_long(reg);
! 118: /* if invalid tag, return -1 */
! 119: if (reg == 0xffffffff) {
! 120: return 0xffffffff;
! 121: }
! 122:
! 123: CF8 = reg;
! 124: xx = CF8;
! 125: data = CFC;
! 126: data = md_swap_long(data);
! 127:
! 128: CF8 = 0;
! 129:
! 130: return(data);
! 131: }
! 132:
! 133: void
! 134: bugpci_conf_write(bus, dev, func, offset, data)
! 135: int bus, dev, func, offset;
! 136: unsigned data;
! 137: {
! 138: unsigned reg, tag, xx;
! 139:
! 140: tag = bugpci_make_tag(bus, dev, func);
! 141: reg = bugpci_gen_config_reg(tag, offset);
! 142: reg = md_swap_long(reg);
! 143:
! 144: /* if invalid tag, return ??? */
! 145: if (reg == 0xffffffff) {
! 146: return;
! 147: }
! 148:
! 149: CF8 = reg;
! 150: xx = CF8;
! 151: data = md_swap_long(data);
! 152: CFC = data;
! 153: CF8 = 0;
! 154: xx = CF8;
! 155: }
! 156: #endif
! 157:
! 158: static u_long
! 159: get_long(p)
! 160: const void *p;
! 161: {
! 162: const unsigned char *cp = p;
! 163:
! 164: return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
! 165: }
! 166:
! 167: /*
! 168: * Find a valid disklabel.
! 169: */
! 170: static int
! 171: search_label(devp, off, buf, lp, off0)
! 172: void *devp;
! 173: u_long off;
! 174: char *buf;
! 175: struct disklabel *lp;
! 176: u_long off0;
! 177: {
! 178: size_t read;
! 179: struct dos_partition *p;
! 180: int i;
! 181: u_long poff;
! 182: static int recursion;
! 183:
! 184: if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
! 185: || read != DEV_BSIZE)
! 186: return ERDLAB;
! 187:
! 188: if (buf[510] != 0x55 || buf[511] != 0xaa)
! 189: return ERDLAB;
! 190:
! 191: if (recursion++ <= 1)
! 192: off0 += off;
! 193: for (p = (struct dos_partition *)(buf + DOSPARTOFF), i = 4;
! 194: --i >= 0; p++) {
! 195: if (p->dp_typ == DOSPTYP_OPENBSD) {
! 196: poff = get_long(&p->dp_start) + off0;
! 197: if (dsk_strategy(devp, F_READ, poff + LABELSECTOR,
! 198: DEV_BSIZE, buf, &read) == 0
! 199: && read == DEV_BSIZE) {
! 200: if (!getdisklabel(buf, lp)) {
! 201: recursion--;
! 202: return 0;
! 203: }
! 204: }
! 205: if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
! 206: || read != DEV_BSIZE) {
! 207: recursion--;
! 208: return ERDLAB;
! 209: }
! 210: } else if (p->dp_typ == DOSPTYP_EXTEND) {
! 211: poff = get_long(&p->dp_start);
! 212: if (!search_label(devp, poff, buf, lp, off0)) {
! 213: recursion--;
! 214: return 0;
! 215: }
! 216: if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
! 217: || read != DEV_BSIZE) {
! 218: recursion--;
! 219: return ERDLAB;
! 220: }
! 221: }
! 222: }
! 223: recursion--;
! 224: return ERDLAB;
! 225: }
! 226:
! 227: int dsk_read_disklabel(devp)
! 228: void *devp;
! 229: {
! 230: static char iobuf[MAXBSIZE];
! 231: struct disklabel label;
! 232: int error = 0;
! 233: int i;
! 234:
! 235: register struct bugdev_softc *pp = (struct bugdev_softc *)devp;
! 236:
! 237: #ifdef DEBUG
! 238: printf("dsk_open:\n");
! 239: #endif
! 240: /* First try to find a disklabel without MBR partitions */
! 241: if (dsk_strategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &i) != 0
! 242: || i != DEV_BSIZE
! 243: || getdisklabel(iobuf, &label)) {
! 244: /* Else try MBR partitions */
! 245: error = search_label(pp, 0, iobuf, &label, 0);
! 246: if (error && error != ERDLAB)
! 247: return (error);
! 248: }
! 249: if (error == ERDLAB) {
! 250: if (pp->pnum)
! 251: /* User specified a partition, but there is none */
! 252: return (error);
! 253: /* No, label, just use complete disk */
! 254: pp->poff = 0;
! 255: } else {
! 256: pp->poff = label.d_partitions[pp->pnum].p_offset;
! 257: pp->psize = label.d_partitions[pp->pnum].p_size;
! 258: }
! 259: return(0);
! 260: }
! 261:
! 262:
! 263: int
! 264: devopen(f, fname, file)
! 265: struct open_file *f;
! 266: const char *fname;
! 267: char **file;
! 268: {
! 269: register struct bugdev_softc *pp = &bugdev_softc[0];
! 270: int error;
! 271: char *dev, *cp;
! 272:
! 273: pp->clun = (short)bugargs.ctrl_lun;
! 274: pp->dlun = (short)bugargs.dev_lun;
! 275: pp->poff = 0;
! 276: pp->psize = 0;
! 277: pp->fd = 0;
! 278: pp->pnum = 0;
! 279:
! 280: f->f_devdata = (void *)pp;
! 281:
! 282: switch (bootdev_type) {
! 283: case BUGDEV_DISK:
! 284: dev = bugargs.arg_start;
! 285: /*
! 286: * Extract partition # from boot device string.
! 287: */
! 288: for (cp = dev; *cp; cp++) /* void */;
! 289: while (*cp != '/' && cp > dev) {
! 290: if (*cp == ':')
! 291: pp->pnum = *(cp+1) - 'a';
! 292: --cp;
! 293: }
! 294:
! 295: error = dsk_read_disklabel(pp);
! 296: if (error)
! 297: return(error);
! 298:
! 299: bcopy(&ufs_file_system, file_system, sizeof file_system[0]);
! 300: break;
! 301:
! 302: case BUGDEV_NET:
! 303: bcopy(&tftp_file_system, file_system, sizeof file_system[0]);
! 304: break;
! 305:
! 306: case BUGDEV_TAPE:
! 307: bcopy(&raw_file_system, file_system, sizeof file_system[0]);
! 308: break;
! 309: }
! 310:
! 311: f->f_dev = &devsw[bootdev_type];
! 312: nfsys = 1;
! 313: *file = (char *)fname;
! 314: return (0);
! 315: }
! 316:
! 317: /* silly block scale factor */
! 318: #define BUG_BLOCK_SIZE 256
! 319: #define BUG_SCALE (512/BUG_BLOCK_SIZE)
! 320: int
! 321: dsk_strategy(devdata, func, dblk, size, buf, rsize)
! 322: void *devdata;
! 323: int func;
! 324: daddr_t dblk;
! 325: size_t size;
! 326: void *buf;
! 327: size_t *rsize;
! 328: {
! 329: struct mvmeprom_dskio dio;
! 330: register struct bugdev_softc *pp = (struct bugdev_softc *)devdata;
! 331: daddr_t blk = dblk + pp->poff;
! 332:
! 333: twiddle();
! 334:
! 335: dio.ctrl_lun = pp->clun;
! 336: dio.dev_lun = pp->dlun;
! 337: dio.status = 0;
! 338: dio.pbuffer = buf;
! 339: dio.blk_num = blk * BUG_SCALE;
! 340: dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
! 341: dio.flag = 0;
! 342: dio.addr_mod = 0;
! 343: #ifdef DEBUG
! 344: printf("dsk_strategy: size=%d blk=%d buf=%x\n", size, blk, buf);
! 345: printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
! 346: #endif
! 347: mvmeprom_diskrd(&dio);
! 348:
! 349: *rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
! 350: #ifdef DEBUG
! 351: printf("rsize %d status %x\n", *rsize, dio.status);
! 352: #endif
! 353:
! 354: if (dio.status)
! 355: return (EIO);
! 356: return (0);
! 357: }
! 358:
! 359: int
! 360: dsk_open(f)
! 361: struct open_file *f;
! 362: {
! 363: #ifdef DEBUG
! 364: register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata;
! 365: printf("dsk_open:\n");
! 366: printf("using mvmebug ctrl %d dev %d\n",
! 367: pp->clun, pp->dlun);
! 368: #endif
! 369: return (0);
! 370: }
! 371:
! 372: int
! 373: dsk_close(f)
! 374: struct open_file *f;
! 375: {
! 376: return (EIO);
! 377: }
! 378:
! 379: int
! 380: dsk_ioctl(f, cmd, data)
! 381: struct open_file *f;
! 382: u_long cmd;
! 383: void *data;
! 384: {
! 385: return (EIO);
! 386: }
! 387:
! 388: #define NFR_TIMEOUT 5
! 389: /* netboot stuff */
! 390: int
! 391: net_strategy(devdata, func, nblk, size, buf, rsize)
! 392: void *devdata;
! 393: int func;
! 394: daddr_t nblk;
! 395: size_t size;
! 396: void *buf;
! 397: size_t *rsize;
! 398: {
! 399: int attempts = 0;
! 400: struct mvmeprom_netfread nfr;
! 401: register struct bugdev_softc *pp = (struct bugdev_softc *)devdata;
! 402:
! 403: retry:
! 404:
! 405: attempts+=1;
! 406:
! 407: nfr.clun = pp->clun;
! 408: nfr.dlun = pp->dlun;
! 409: nfr.status = 0;
! 410: nfr.addr = buf;
! 411: nfr.bytes = 0;
! 412: nfr.blk = nblk;
! 413: nfr.timeout = NFR_TIMEOUT;
! 414: #ifdef DEBUG
! 415: printf("net_strategy: size=%d blk=%d buf=%x\n", size, nblk, buf);
! 416: printf("ctrl %d dev %d\n", nfr.clun, nfr.dlun);
! 417: #endif
! 418: mvmeprom_netfread(&nfr);
! 419:
! 420: #ifdef BUG_DEBUG
! 421: io = bugpci_conf_read(0, 14, 0, 0x10) & ~0xf;
! 422: mem = bugpci_conf_read(0, 14, 0, 0x14) & ~0xf;
! 423:
! 424: printf(" IO @ %x\n", io);
! 425: printf("MEM @ %x\n", mem);
! 426:
! 427: #define PRINT_REG(regname, x) printf("%s = 0x%x\n", regname, \
! 428: md_swap_long(*(unsigned *)(io + x)))
! 429:
! 430: PRINT_REG("CSR0", 0x00);
! 431: PRINT_REG("CSR1", 0x08);
! 432: PRINT_REG("CSR2", 0x10);
! 433: PRINT_REG("CSR3", 0x18);
! 434: PRINT_REG("CSR4", 0x20);
! 435: PRINT_REG("CSR5", 0x28);
! 436: PRINT_REG("CSR6", 0x30);
! 437: PRINT_REG("CSR7", 0x38);
! 438: PRINT_REG("CSR8", 0x40);
! 439: PRINT_REG("CSR9", 0x48);
! 440: PRINT_REG("CSR10", 0x50);
! 441: PRINT_REG("CSR11", 0x58);
! 442: PRINT_REG("CSR12", 0x60);
! 443: PRINT_REG("CSR13", 0x68);
! 444: PRINT_REG("CSR14", 0x70);
! 445: PRINT_REG("CSR15", 0x78);
! 446: #endif
! 447: if (rsize) {
! 448: *rsize = nfr.bytes;
! 449: }
! 450: #ifdef DEBUG
! 451: printf("rsize %d status %x\n", *rsize, nfr.status);
! 452: #endif
! 453:
! 454: if (nfr.status)
! 455: if (attempts < 10)
! 456: goto retry;
! 457: else
! 458: return (EIO);
! 459: return (0);
! 460: }
! 461:
! 462: int
! 463: net_open(struct open_file *f, ...)
! 464: {
! 465: va_list ap;
! 466: struct mvmeprom_netfopen nfo;
! 467: register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata;
! 468: char *filename;
! 469: short nfoerr = 0;
! 470: va_start(ap, f);
! 471: filename = va_arg(ap, char *);
! 472: va_end(ap);
! 473:
! 474: #ifdef DEBUG
! 475: printf("net_open: using mvmebug ctrl %d dev %d, filename: %s\n",
! 476: pp->clun, pp->dlun, filename);
! 477: #endif
! 478: nfo.clun = pp->clun;
! 479: nfo.dlun = pp->dlun;
! 480: nfo.status = 0;
! 481: strlcpy(nfo.filename, filename, sizeof nfo.filename);
! 482: /* .NETFOPN syscall */
! 483: mvmeprom_netfopen(&nfo);
! 484:
! 485: #ifdef DEBUG
! 486: if (nfo.status) {
! 487: nfoerr = nfo.status;
! 488: printf("net_open: ci err = 0x%x, cd err = 0x%x\n",
! 489: ((nfoerr >> 8) & 0x0F), (nfoerr & 0x0F));
! 490: }
! 491: #endif
! 492: return (nfo.status);
! 493: }
! 494:
! 495: int
! 496: net_close(f)
! 497: struct open_file *f;
! 498: {
! 499: return (EIO);
! 500: }
! 501:
! 502: int
! 503: net_ioctl(f, cmd, data)
! 504: struct open_file *f;
! 505: u_long cmd;
! 506: void *data;
! 507: {
! 508: return (EIO);
! 509: }
! 510:
! 511: int
! 512: tape_open(struct open_file *f, ...)
! 513: {
! 514: va_list ap;
! 515: int error = 0;
! 516: int part;
! 517: struct mvmeprom_dskio *ti;
! 518: char *fname; /* partition number, i.e. "1" */
! 519:
! 520: va_start(ap, f);
! 521: fname = va_arg(ap, char *);
! 522: va_end(ap);
! 523:
! 524: /*
! 525: * Set the tape segment number to the one indicated
! 526: * by the single digit fname passed in above.
! 527: */
! 528: if ((fname[0] < '0') && (fname[0] > '9')) {
! 529: return ENOENT;
! 530: }
! 531: part = fname[0] - '0';
! 532: fname = NULL;
! 533:
! 534: /*
! 535: * Setup our part of the saioreq.
! 536: * (determines what gets opened)
! 537: */
! 538: ti = &tape_ioreq;
! 539: bzero((caddr_t)ti, sizeof(*ti));
! 540:
! 541: ti->ctrl_lun = bugargs.ctrl_lun;
! 542: ti->dev_lun = bugargs.dev_lun;
! 543: ti->status = 0;
! 544: ti->pbuffer = NULL;
! 545: ti->blk_num = part;
! 546: ti->blk_cnt = 0;
! 547: ti->flag = 0;
! 548: ti->addr_mod = 0;
! 549:
! 550: f->f_devdata = ti;
! 551:
! 552: return (0);
! 553: }
! 554:
! 555: int
! 556: tape_close(f)
! 557: struct open_file *f;
! 558: {
! 559: struct mvmeprom_dskio *ti;
! 560:
! 561:
! 562: ti = f->f_devdata;
! 563: f->f_devdata = NULL;
! 564: return 0;
! 565: }
! 566:
! 567: #define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE)
! 568:
! 569: int
! 570: tape_strategy(devdata, flag, dblk, size, buf, rsize)
! 571: void *devdata;
! 572: int flag;
! 573: daddr_t dblk;
! 574: size_t size;
! 575: void *buf;
! 576: size_t *rsize;
! 577: {
! 578: struct mvmeprom_dskio *ti;
! 579: int ret;
! 580:
! 581: ti = devdata;
! 582:
! 583: if (flag != F_READ)
! 584: return(EROFS);
! 585:
! 586: ti->status = 0;
! 587: ti->pbuffer = buf;
! 588: /* don't change block #, set in open */
! 589: ti->blk_cnt = size / (512 / MVMEPROM_SCALE);
! 590:
! 591: ret = mvmeprom_diskrd(ti);
! 592:
! 593: if (ret != 0)
! 594: return (EIO);
! 595:
! 596: *rsize = (ti->blk_cnt / MVMEPROM_SCALE) * 512;
! 597: ti->flag |= IGNORE_FILENUM; /* ignore next time */
! 598:
! 599: return (0);
! 600: }
! 601:
! 602: int
! 603: tape_ioctl(f, cmd, data)
! 604: struct open_file *f;
! 605: u_long cmd;
! 606: void *data;
! 607: {
! 608: return EIO;
! 609: }
! 610:
! 611:
CVSweb