1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)xp.c	2.3 (2.11BSD) 1996/3/8
   7:  */
   8: 
   9: /*
  10:  * SMD disk driver
  11:  */
  12: #include "../h/param.h"
  13: #include "../pdpuba/hpreg.h"
  14: #include "../machine/iopage.h"
  15: #include "saio.h"
  16: 
  17: #define NXP 2
  18: 
  19:     struct  hpdevice *XPcsr[NXP + 1] =
  20:         {
  21:         (struct hpdevice *)0176700,
  22:         (struct hpdevice *)0,
  23:         (struct hpdevice *)-1
  24:         };
  25: 
  26:     static  char    xpinit[NXP][8];     /* XXX */
  27: 
  28: xpopen(io)
  29:     register struct iob *io;
  30:     {
  31:     register struct disklabel *lp = &io->i_label;
  32:     register struct hpdevice *xpaddr;
  33:     int dummy;
  34: 
  35:     if  (genopen(NXP, io) < 0)
  36:         return(-1);
  37: /*
  38:  * If this is the first access for the drive check to see if it is
  39:  * present.  If the drive is present then read the label.
  40: */
  41:     if  (xpinit[io->i_ctlr][io->i_unit] == 0)
  42:         {
  43:         xpaddr = XPcsr[io->i_ctlr];
  44:         xpaddr->hpcs1.w = HP_NOP;
  45:         xpaddr->hpcs2.w = io->i_unit;
  46:         xpaddr->hpcs1.w = HP_GO;
  47:         delay(6000);
  48:         dummy = xpaddr->hpds;
  49:         if  (xpaddr->hpcs2.w & HPCS2_NED)
  50:             {
  51:             xpaddr->hpcs2.w = HPCS2_CLR;
  52:             return(-1);
  53:             }
  54:         if  (devlabel(io, READLABEL) == -1)
  55:             return(-1);
  56:         xpinit[io->i_ctlr][io->i_unit] = 1;
  57:         }
  58:     io->i_boff = lp->d_partitions[io->i_part].p_offset;
  59:     return(0);
  60:     }
  61: 
  62: xpclose(io)
  63:     struct  iob *io;
  64:     {
  65: 
  66:     xpinit[io->i_ctlr][io->i_unit] = 0;
  67:     return(0);
  68:     }
  69: 
  70: xpstrategy(io, func)
  71:     register struct iob *io;
  72: {
  73:     int i;
  74:     daddr_t bn;
  75:     int sn, cn, tn, bae, lo16;
  76:     register struct hpdevice *xpaddr = XPcsr[io->i_ctlr];
  77:     register struct disklabel *lp = &io->i_label;
  78: 
  79:     i = deveovchk(io);
  80:     if  (i <= 0)
  81:         return(i);
  82: 
  83:     bn = io->i_bn;
  84:     xpaddr->hpcs2.w = io->i_unit;
  85: 
  86:     if ((xpaddr->hpds & HPDS_VV) == 0) {
  87:         xpaddr->hpcs1.c[0] = HP_PRESET|HP_GO;
  88:         xpaddr->hpof = HPOF_FMT22;
  89:     }
  90:     cn = bn / lp->d_secpercyl;
  91:     sn = bn % lp->d_secpercyl;
  92:     tn = sn / lp->d_nsectors;
  93:     sn = sn % lp->d_nsectors;
  94: 
  95:     iomapadr(io->i_ma, &bae, &lo16);
  96:     xpaddr->hpdc = cn;
  97:     xpaddr->hpda = (tn << 8) + sn;
  98:     xpaddr->hpba = (caddr_t)lo16;
  99:     xpaddr->hpwc = -(io->i_cc>>1);
 100:     i = (bae << 8) | HP_GO;
 101:     if (func == READ)
 102:         i |= HP_RCOM;
 103:     else if (func == WRITE)
 104:         i |= HP_WCOM;
 105:     xpaddr->hpcs1.w = i;
 106:     while ((xpaddr->hpcs1.w & HP_RDY) == 0)
 107:             continue;
 108:     if (xpaddr->hpcs1.w & HP_TRE) {
 109:         printf("%s err cy=%d tr=%d sc=%d cs2=%o er1=%o\n",
 110:             devname(io), cn, tn, sn, xpaddr->hpcs2,
 111:             xpaddr->hper1);
 112:         return(-1);
 113:     }
 114:     return(io->i_cc);
 115: }
 116: 
 117: /*
 118:  * ALL drive type identification has been removed from the kernel's XP
 119:  * driver and placed here.
 120:  *
 121:  * These tables are used to provide "the best guess" of the geometry
 122:  * of the drive.  DEC RP0{4,5,6,7} and RM0{3,5} drives will match exactly.
 123:  * Non DEC controllers (performing an emulation) often use the DEC drive
 124:  * type to mean completely different geometry/capacity drives.
 125: */
 126: 
 127:     struct  xpst
 128:         {
 129:         int flags;      /* flags: XP_CC, XP_NOSEARCH */
 130:         int ncyl;       /* number of cylinders */
 131:         int nspc;       /* number of sectors per cylinder */
 132:         int ntpc;       /* number of tracks per cylinder */
 133:         int nspt;       /* number of sectors per track */
 134:         daddr_t nspd;       /* number of sectors per drive */
 135:         };
 136: 
 137: static struct   xpst rp04_st = { XP_CC, 411, 22 * 19, 19, 22, 411L * 22 * 19 };
 138: /* rp05 uses same table as rp04 */
 139: static struct   xpst rp06_st = { XP_CC, 815, 22 * 19, 19, 22, 815L * 22 * 19 };
 140: static struct   xpst rp07_st = { XP_CC, 630, 50 * 32, 32, 50, 630L * 50 * 32 };
 141: 
 142: static struct   xpst rm02_st;   /* filled in dynamically */
 143: static struct   xpst rm03_st = { 0, 823, 32 *  5,  5, 32, 823L * 32 *  5 };
 144: static struct   xpst rm05_st = { 0, 823, 32 * 19, 19, 32, 823L * 32 * 19 };
 145: static struct   xpst rm80_st = { 0, 559, 31 * 14, 14, 31, 559L * 31 * 14 };
 146: 
 147: /*
 148:  * SI controller stuff - likely not used any longer and will probably go away
 149:  * eventually (when the D space is needed for something more important).
 150: */
 151: 
 152: static struct   xpst cdc9775_st = { 0, 843, 32 * 40, 40, 32, 843L * 32 * 40 };
 153: static struct   xpst cdc9730_st = { 0, 823, 32 * 10, 10, 32, 823L * 32 * 10 };
 154: static struct   xpst cdc9766_st = { 0, 823, 32 * 19, 19, 32, 823L * 32 * 19 };
 155: static struct   xpst cdc9762_st = { 0, 823, 32 *  5,  5, 32, 823L * 32 *  5 };
 156: static struct   xpst capric_st = { 0, 1024, 32 * 16, 16, 32, 1024L * 32 * 16 };
 157: static struct   xpst eagle_st   = { 0, 842, 48 * 20, 20, 48, 842L * 48 * 20 };
 158: 
 159: /*
 160:  * A "default".  If none of the above are useable then a default geometry
 161:  * suitable for writing a label (sector 1) is used.
 162: */
 163: 
 164: static struct   xpst default_st = { 0, 1, 2 * 1, 1, 2, 2 };
 165: 
 166: /*
 167:  * This routine does not return an error (-1).  If the drive is totally
 168:  * unrecognizeable then the default above is used.
 169: */
 170: 
 171: xplabel(io)
 172:     struct iob *io;
 173:     {
 174:     register struct xpst    *st = NULL;
 175:     int type, xpsn;
 176:     register struct hpdevice *xpaddr = XPcsr[io->i_ctlr];
 177:     register struct disklabel *lp;
 178: 
 179:     type = xpaddr->hpdt & 077;
 180:     switch  (type)
 181:         {
 182:         case    HPDT_RP04:  /* 020 */
 183:         case    HPDT_RP05:  /* 021 */
 184:             st = &rp04_st;
 185:             break;
 186:         case    HPDT_RP06:  /* 022 */
 187:             st = &rp06_st;
 188:             break;
 189:         case    HPDT_RP07:  /* 042 */
 190:             st = &rp07_st;
 191:             break;
 192:         case    HPDT_RM80:  /* 026 */
 193:             st = &rm80_st;
 194:             break;
 195:         case    HPDT_RM05:  /* 027 */
 196:             st = &rm05_st;
 197:             break;
 198:         case    HPDT_RM03:  /* 024 */
 199:             st = &rm03_st;
 200:             break;
 201:         case    HPDT_RM02:  /* 025 */
 202: /*
 203:  * Borrowing a quote from 4BSD:
 204:  *  "We know this isn't a dec controller, so we can assume sanity."
 205: */
 206:             st = &rm02_st;
 207:             xpaddr->hpcs1.w = HP_NOP;
 208:             xpaddr->hpcs2.w = io->i_unit;
 209: 
 210:             xpaddr->rmhr = HPHR_MAXTRAK;
 211:             st->ntpc = xpaddr->rmhr + 1;
 212: 
 213:             xpaddr->rmhr = HPHR_MAXSECT;
 214:             st->nspt = xpaddr->rmhr + 1;
 215: 
 216:             xpaddr->rmhr = HPHR_MAXCYL;
 217:             st->ncyl = xpaddr->rmhr + 1;
 218: 
 219:             xpaddr->hpcs1.w = HP_DCLR | HP_GO;
 220: 
 221:             st->nspc = st->nspt * st->ntpc;
 222:             st->nspd = (long)st->nspc * st->ncyl;
 223:             printf("type: RM02 c=%d t/c=%d s/t=%d\n", st->ncyl,
 224:                 st->ntpc, st->nspt);
 225:             break;
 226:         default:
 227:             printf("%s unknown drive type: %d -- ",
 228:                 devname(io), type);
 229:             printf("using 1 cyl, 1 trk, 2 sec/trk\n");
 230:             st = &default_st;
 231:             break;
 232:         }
 233: 
 234: /*
 235:  * Handle SI model byte stuff when we think it's an RM05 or RM03.  Is any
 236:  * one still using one of these?  Is it worth all this code?
 237: */
 238:     if  (type == HPDT_RM05 || type == HPDT_RM03)
 239:         {
 240:         xpsn = xpaddr->hpsn;
 241:         if  ((xpsn & SIMB_LU) != io->i_unit)
 242:             goto notsi;
 243:         switch  ((xpsn & SIMB_MB) &~ (SIMB_S6|SIRM03|SIRM05))
 244:             {
 245:             case    SI9775D:
 246:                 st = &cdc9775_st;
 247:                 break;
 248:             case    SI9730D:
 249:                 st = &cdc9730_st;
 250:                 break;
 251:             case    SI9766:
 252:                 st = &cdc9766_st;
 253:                 break;
 254:             case    SI9762:
 255:                 st = &cdc9762_st;
 256:                 break;
 257:             case    SICAPD:
 258:                 st = &capric_st;
 259:                 break;
 260:             case    SI9751D:
 261:                 st = &eagle_st;
 262:                 break;
 263:             default:
 264:                 printf("%s unknown SI drive model %d -- ",
 265:                     devname(io), xpsn);
 266:                 printf("using 1 cyl, 1 trk, 2 sec/trk\n");
 267:                 st = &default_st;
 268:                 break;
 269:             }
 270:         }
 271: notsi:
 272:     lp = &io->i_label;
 273:     lp->d_type = DTYPE_SMD;
 274:     lp->d_secsize = 512;    /* XXX */
 275:     lp->d_secperunit = st->nspd;
 276:     lp->d_partitions[0].p_size = st->nspd;
 277:     lp->d_nsectors = st->nspt;
 278:     lp->d_ntracks = st->ntpc;
 279:     lp->d_secpercyl = st->nspc;
 280:     lp->d_ncylinders = st->ncyl;
 281:     lp->d_drivedata[0] = st->flags;
 282:     strcpy(lp->d_typename, "SMD");
 283:     return(0);
 284:     }

Defined functions

xpclose defined in line 62; used 2 times
xplabel defined in line 171; used 2 times
xpopen defined in line 28; used 2 times
xpstrategy defined in line 70; used 2 times

Defined variables

XPcsr defined in line 19; used 4 times
capric_st defined in line 156; used 1 times
cdc9730_st defined in line 153; used 1 times
cdc9762_st defined in line 155; used 1 times
cdc9766_st defined in line 154; used 1 times
cdc9775_st defined in line 152; used 1 times
default_st defined in line 164; used 2 times
eagle_st defined in line 157; used 1 times
rm02_st defined in line 142; used 1 times
rm03_st defined in line 143; used 1 times
rm05_st defined in line 144; used 1 times
rm80_st defined in line 145; used 1 times
rp04_st defined in line 137; used 1 times
rp06_st defined in line 139; used 1 times
rp07_st defined in line 140; used 1 times
xpinit defined in line 26; used 3 times

Defined struct's

xpst defined in line 127; used 30 times

Defined macros

NXP defined in line 17; used 3 times
Last modified: 1996-03-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3643
Valid CSS Valid XHTML 1.0 Strict