Annotation of sys/arch/hp300/stand/common/hd.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: hd.c,v 1.6 2006/08/17 06:31:10 miod Exp $ */
! 2: /* $NetBSD: rd.c,v 1.11 1996/12/21 21:34:40 thorpej Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1988 University of Utah.
! 6: * Copyright (c) 1982, 1990, 1993
! 7: * The Regents of the University of California. All rights reserved.
! 8: *
! 9: * This code is derived from software contributed to Berkeley by
! 10: * the Systems Programming Group of the University of Utah Computer
! 11: * Science Department.
! 12: *
! 13: * Redistribution and use in source and binary forms, with or without
! 14: * modification, are permitted provided that the following conditions
! 15: * are met:
! 16: * 1. Redistributions of source code must retain the above copyright
! 17: * notice, this list of conditions and the following disclaimer.
! 18: * 2. Redistributions in binary form must reproduce the above copyright
! 19: * notice, this list of conditions and the following disclaimer in the
! 20: * documentation and/or other materials provided with the distribution.
! 21: * 3. Neither the name of the University nor the names of its contributors
! 22: * may be used to endorse or promote products derived from this software
! 23: * without specific prior written permission.
! 24: *
! 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 35: * SUCH DAMAGE.
! 36: *
! 37: * from: Utah Hdr: rd.c 1.20 92/12/21
! 38: *
! 39: * @(#)rd.c 8.1 (Berkeley) 7/15/93
! 40: */
! 41:
! 42: /*
! 43: * CS80/SS80 disk driver
! 44: */
! 45: #include <sys/param.h>
! 46: #include <sys/disklabel.h>
! 47:
! 48: #include <lib/libsa/stand.h>
! 49:
! 50: #include "samachdep.h"
! 51:
! 52: #include <hp300/dev/hdreg.h>
! 53: #include "hpibvar.h"
! 54:
! 55: struct hd_iocmd hd_ioc;
! 56: struct hd_rscmd hd_rsc;
! 57: struct hd_stat hd_stat;
! 58: struct hd_ssmcmd hd_ssmc;
! 59:
! 60: struct disklabel hdlabel;
! 61:
! 62: struct hdminilabel {
! 63: u_short npart;
! 64: u_long offset[MAXPARTITIONS];
! 65: };
! 66:
! 67: struct hd_softc {
! 68: int sc_ctlr;
! 69: int sc_unit;
! 70: int sc_part;
! 71: char sc_retry;
! 72: char sc_alive;
! 73: short sc_type;
! 74: struct hdminilabel sc_pinfo;
! 75: } hd_softc[NHPIB][NHD];
! 76:
! 77: #define HDRETRY 5
! 78:
! 79: struct hdidentinfo {
! 80: short ri_hwid;
! 81: short ri_maxunum;
! 82: int ri_nblocks;
! 83: } hdidentinfo[] = {
! 84: { HD7946AID, 0, 108416 },
! 85: { HD9134DID, 1, 29088 },
! 86: { HD9134LID, 1, 1232 },
! 87: { HD7912PID, 0, 128128 },
! 88: { HD7914PID, 0, 258048 },
! 89: { HD7958AID, 0, 255276 },
! 90: { HD7957AID, 0, 159544 },
! 91: { HD7933HID, 0, 789958 },
! 92: { HD9134LID, 1, 77840 },
! 93: { HD7936HID, 0, 600978 },
! 94: { HD7937HID, 0, 1116102 },
! 95: { HD7914CTID, 0, 258048 },
! 96: { HD7946AID, 0, 108416 },
! 97: { HD9134LID, 1, 1232 },
! 98: { HD7957BID, 0, 159894 },
! 99: { HD7958BID, 0, 297108 },
! 100: { HD7959BID, 0, 594216 },
! 101: { HD2200AID, 0, 654948 },
! 102: { HD2203AID, 0, 1309896 }
! 103: };
! 104: int numhdidentinfo = sizeof(hdidentinfo) / sizeof(hdidentinfo[0]);
! 105:
! 106: int hdclose(struct open_file *);
! 107: int hderror(int, int, int);
! 108: int hdgetinfo(struct hd_softc *);
! 109: int hdident(int, int);
! 110: int hdinit(int, int);
! 111: int hdopen(struct open_file *, int, int, int);
! 112: void hdreset(int, int);
! 113: int hdstrategy(void *, int, daddr_t, size_t, void *, size_t *);
! 114:
! 115: int
! 116: hdinit(int ctlr, int unit)
! 117: {
! 118: struct hd_softc *rs = &hd_softc[ctlr][unit];
! 119:
! 120: rs->sc_type = hdident(ctlr, unit);
! 121: if (rs->sc_type < 0)
! 122: return (0);
! 123: rs->sc_alive = 1;
! 124: return (1);
! 125: }
! 126:
! 127: void
! 128: hdreset(int ctlr, int unit)
! 129: {
! 130: u_char stat;
! 131:
! 132: hd_ssmc.c_unit = C_SUNIT(0);
! 133: hd_ssmc.c_cmd = C_SSM;
! 134: hd_ssmc.c_refm = REF_MASK;
! 135: hd_ssmc.c_fefm = FEF_MASK;
! 136: hd_ssmc.c_aefm = AEF_MASK;
! 137: hd_ssmc.c_iefm = IEF_MASK;
! 138: hpibsend(ctlr, unit, C_CMD, &hd_ssmc, sizeof(hd_ssmc));
! 139: hpibswait(ctlr, unit);
! 140: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
! 141: }
! 142:
! 143: int
! 144: hdident(int ctlr, int unit)
! 145: {
! 146: struct cs80_describe desc;
! 147: u_char stat, cmd[3];
! 148: char name[7];
! 149: int id, i;
! 150:
! 151: id = hpibid(ctlr, unit);
! 152: if ((id & 0x200) == 0)
! 153: return(-1);
! 154: for (i = 0; i < numhdidentinfo; i++)
! 155: if (id == hdidentinfo[i].ri_hwid)
! 156: break;
! 157: if (i == numhdidentinfo)
! 158: return(-1);
! 159: id = i;
! 160: hdreset(ctlr, unit);
! 161: cmd[0] = C_SUNIT(0);
! 162: cmd[1] = C_SVOL(0);
! 163: cmd[2] = C_DESC;
! 164: hpibsend(ctlr, unit, C_CMD, cmd, sizeof(cmd));
! 165: hpibrecv(ctlr, unit, C_EXEC, &desc, sizeof(desc));
! 166: hpibrecv(ctlr, unit, C_QSTAT, &stat, sizeof(stat));
! 167: bzero(name, sizeof(name));
! 168: if (!stat) {
! 169: int n = desc.d_name;
! 170: for (i = 5; i >= 0; i--) {
! 171: name[i] = (n & 0xf) + '0';
! 172: n >>= 4;
! 173: }
! 174: }
! 175: /*
! 176: * Take care of a couple of anomalies:
! 177: * 1. 7945A and 7946A both return same HW id
! 178: * 2. 9122S and 9134D both return same HW id
! 179: * 3. 9122D and 9134L both return same HW id
! 180: */
! 181: switch (hdidentinfo[id].ri_hwid) {
! 182: case HD7946AID:
! 183: if (bcmp(name, "079450", 6) == 0)
! 184: id = HD7945A;
! 185: else
! 186: id = HD7946A;
! 187: break;
! 188:
! 189: case HD9134LID:
! 190: if (bcmp(name, "091340", 6) == 0)
! 191: id = HD9134L;
! 192: else
! 193: id = HD9122D;
! 194: break;
! 195:
! 196: case HD9134DID:
! 197: if (bcmp(name, "091220", 6) == 0)
! 198: id = HD9122S;
! 199: else
! 200: id = HD9134D;
! 201: break;
! 202: }
! 203: return(id);
! 204: }
! 205:
! 206: char io_buf[MAXBSIZE];
! 207:
! 208: int
! 209: hdgetinfo(struct hd_softc *rs)
! 210: {
! 211: struct hdminilabel *pi = &rs->sc_pinfo;
! 212: struct disklabel *lp = &hdlabel;
! 213: char *msg;
! 214: int err, savepart;
! 215: size_t i;
! 216:
! 217: bzero((caddr_t)lp, sizeof *lp);
! 218: lp->d_secsize = DEV_BSIZE;
! 219:
! 220: /* Disklabel is always from RAW_PART. */
! 221: savepart = rs->sc_part;
! 222: rs->sc_part = RAW_PART;
! 223: err = hdstrategy(rs, F_READ, LABELSECTOR,
! 224: lp->d_secsize ? lp->d_secsize : DEV_BSIZE, io_buf, &i);
! 225: rs->sc_part = savepart;
! 226:
! 227: if (err) {
! 228: printf("hdgetinfo: hdstrategy error %d\n", err);
! 229: return(0);
! 230: }
! 231:
! 232: msg = getdisklabel(io_buf, lp);
! 233: if (msg) {
! 234: printf("hd(%d,%d,%d): WARNING: %s, ",
! 235: rs->sc_ctlr, rs->sc_unit, rs->sc_part, msg);
! 236: printf("defining `c' partition as entire disk\n");
! 237: pi->npart = 3;
! 238: pi->offset[0] = pi->offset[1] = -1;
! 239: pi->offset[2] = 0;
! 240: } else {
! 241: pi->npart = lp->d_npartitions;
! 242: for (i = 0; i < pi->npart; i++)
! 243: pi->offset[i] = lp->d_partitions[i].p_size == 0 ?
! 244: -1 : lp->d_partitions[i].p_offset;
! 245: }
! 246: return(1);
! 247: }
! 248:
! 249: int
! 250: hdopen(struct open_file *f, int ctlr, int unit, int part)
! 251: {
! 252: struct hd_softc *rs;
! 253:
! 254: if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
! 255: return (EADAPT);
! 256: if (unit >= NHD)
! 257: return (ECTLR);
! 258: rs = &hd_softc[ctlr][unit];
! 259: rs->sc_part = part;
! 260: rs->sc_unit = unit;
! 261: rs->sc_ctlr = ctlr;
! 262: if (rs->sc_alive == 0) {
! 263: if (hdinit(ctlr, unit) == 0)
! 264: return (ENXIO);
! 265: if (hdgetinfo(rs) == 0)
! 266: return (ERDLAB);
! 267: }
! 268: if (part != RAW_PART && /* always allow RAW_PART to be opened */
! 269: (part >= rs->sc_pinfo.npart || rs->sc_pinfo.offset[part] == -1))
! 270: return (EPART);
! 271: f->f_devdata = (void *)rs;
! 272: return (0);
! 273: }
! 274:
! 275: int
! 276: hdclose(struct open_file *f)
! 277: {
! 278: struct hd_softc *rs = f->f_devdata;
! 279:
! 280: /*
! 281: * Mark the disk `not alive' so that the disklabel
! 282: * will be re-loaded at next open.
! 283: */
! 284: bzero(rs, sizeof(struct hd_softc));
! 285: f->f_devdata = NULL;
! 286: return (0);
! 287: }
! 288:
! 289: int
! 290: hdstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf,
! 291: size_t *rsize)
! 292: {
! 293: char *buf = v_buf;
! 294: struct hd_softc *rs = devdata;
! 295: int ctlr = rs->sc_ctlr;
! 296: int unit = rs->sc_unit;
! 297: daddr_t blk;
! 298: char stat;
! 299:
! 300: if (size == 0)
! 301: return(0);
! 302:
! 303: /*
! 304: * Don't do partition translation on the `raw partition'.
! 305: */
! 306: blk = (dblk + ((rs->sc_part == RAW_PART) ? 0 :
! 307: rs->sc_pinfo.offset[rs->sc_part]));
! 308:
! 309: rs->sc_retry = 0;
! 310: hd_ioc.c_unit = C_SUNIT(0);
! 311: hd_ioc.c_volume = C_SVOL(0);
! 312: hd_ioc.c_saddr = C_SADDR;
! 313: hd_ioc.c_hiaddr = 0;
! 314: hd_ioc.c_addr = HDBTOS(blk);
! 315: hd_ioc.c_nop2 = C_NOP;
! 316: hd_ioc.c_slen = C_SLEN;
! 317: hd_ioc.c_len = size;
! 318: hd_ioc.c_cmd = func == F_READ ? C_READ : C_WRITE;
! 319: retry:
! 320: hpibsend(ctlr, unit, C_CMD, &hd_ioc.c_unit, sizeof(hd_ioc)-2);
! 321: hpibswait(ctlr, unit);
! 322: hpibgo(ctlr, unit, C_EXEC, buf, size, func);
! 323: hpibswait(ctlr, unit);
! 324: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
! 325: if (stat) {
! 326: if (hderror(ctlr, unit, rs->sc_part) == 0)
! 327: return(EIO);
! 328: if (++rs->sc_retry > HDRETRY)
! 329: return(EIO);
! 330: goto retry;
! 331: }
! 332: *rsize = size;
! 333:
! 334: return(0);
! 335: }
! 336:
! 337: int
! 338: hderror(int ctlr, int unit, int part)
! 339: {
! 340: char stat;
! 341:
! 342: hd_rsc.c_unit = C_SUNIT(0);
! 343: hd_rsc.c_sram = C_SRAM;
! 344: hd_rsc.c_ram = C_RAM;
! 345: hd_rsc.c_cmd = C_STATUS;
! 346: hpibsend(ctlr, unit, C_CMD, &hd_rsc, sizeof(hd_rsc));
! 347: hpibrecv(ctlr, unit, C_EXEC, &hd_stat, sizeof(hd_stat));
! 348: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
! 349: if (stat) {
! 350: printf("hd(%d,%d,0,%d): request status fail %d\n",
! 351: ctlr, unit, part, stat);
! 352: return(0);
! 353: }
! 354: printf("hd(%d,%d,0,%d) err: vu 0x%x",
! 355: ctlr, unit, part, hd_stat.c_vu);
! 356: if ((hd_stat.c_aef & AEF_UD) || (hd_stat.c_ief & (IEF_MD|IEF_RD)))
! 357: printf(", block %ld", hd_stat.c_blk);
! 358: printf(", R0x%x F0x%x A0x%x I0x%x\n",
! 359: hd_stat.c_ref, hd_stat.c_fef, hd_stat.c_aef, hd_stat.c_ief);
! 360: return(1);
! 361: }
CVSweb