1: /*
   2:  *	@(#)uda.c	7.1 (Berkeley) 6/5/86
   3:  */
   4: 
   5: /************************************************************************
   6:  *									*
   7:  *			Copyright (c) 1983 by				*
   8:  *		Digital Equipment Corporation, Maynard, MA		*
   9:  *			All rights reserved.				*
  10:  *									*
  11:  ************************************************************************/
  12: /*
  13:  * uda.c - UDA50A Driver
  14:  *
  15:  * decvax!rich
  16:  */
  17: 
  18: #define DEBUG
  19: #define UDADEVNUM   (9)     /* entry in bdevsw */
  20: #include "ra.h"
  21: #if NUDA > 0
  22: /*
  23:  * UDA50/RAxx disk device driver
  24:  *
  25:  * Restrictions:
  26:  *      Unit numbers must be less than 8.
  27:  */
  28: #include "../machine/pte.h"
  29: 
  30: #include "param.h"
  31: #include "systm.h"
  32: #include "buf.h"
  33: #include "conf.h"
  34: #include "dir.h"
  35: #include "user.h"
  36: #include "map.h"
  37: #include "vm.h"
  38: #include "dk.h"
  39: #include "cmap.h"
  40: #include "uio.h"
  41: 
  42: #include "../vax/cpu.h"
  43: #include "ubareg.h"
  44: #include "ubavar.h"
  45: #include "../vax/mtpr.h"
  46: 
  47: #define TENSEC  (1000)
  48: 
  49: #define NRSPL2  3               /* log2 number of response packets */
  50: #define NCMDL2  3               /* log2 number of command packets */
  51: #define NRSP    (1<<NRSPL2)
  52: #define NCMD    (1<<NCMDL2)
  53: #define UDABURST    4   /* default for DMA burst size */
  54: 
  55: #include "../vaxuba/udareg.h"
  56: #include "../vax/mscp.h"
  57: 
  58: 
  59: struct uda_softc {
  60:     short   sc_state;       /* state of controller */
  61:     short   sc_mapped;      /* Unibus map allocated for uda struct? */
  62:     int     sc_ubainfo;     /* Unibus mapping info */
  63:     struct uda *sc_uda;     /* Unibus address of uda struct */
  64:     int     sc_ivec;        /* interrupt vector address */
  65:     short   sc_credits;     /* transfer credits */
  66:     short   sc_lastcmd;     /* pointer into command ring */
  67:     short   sc_lastrsp;     /* pointer into response ring */
  68: } uda_softc[NUDA];
  69: struct uda {
  70:     struct udaca    uda_ca;         /* communications area */
  71:     struct mscp     uda_rsp[NRSP];  /* response packets */
  72:     struct mscp     uda_cmd[NCMD];  /* command packets */
  73: } uda[NUDA];
  74: 
  75: #define udunit(dev) (minor(dev) >> 3)
  76: 
  77: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
  78: struct size {
  79:     daddr_t nblocks;
  80:     daddr_t blkoff;
  81: }  ra25_sizes[8] = {
  82:     15884,  0,      /* A=blk 0 thru 15883 */
  83:     10032,  15884,      /* B=blk 15884 thru 49323 */
  84:     -1, 0,      /* C=blk 0 thru end */
  85:     0,  0,      /* D=blk 340670 thru 356553 */
  86:     0,  0,      /* E=blk 356554 thru 412489 */
  87:     0,  0,      /* F=blk 412490 thru end */
  88:     -1, 25916,      /* G=blk 49324 thru 131403 */
  89:     0,  0,      /* H=blk 131404 thru end */
  90: }, rd52_sizes[8] = {
  91:     15884,  0,      /* A=blk 0 thru 15883 */
  92:     9766,   15884,      /* B=blk 15884 thru 25649 */
  93:     -1, 0,      /* C=blk 0 thru end */
  94:     0,  0,      /* D=unused */
  95:     0,  0,      /* E=unused */
  96:     0,  0,      /* F=unused */
  97:     -1, 25650,      /* G=blk 25650 thru end */
  98:     0,  0,      /* H=unused */
  99: }, rd53_sizes[8] = {
 100:     15884,  0,      /* A=blk 0 thru 15883 */
 101:     33440,  15884,      /* B=blk 15884 thru 49323 */
 102:     -1, 0,      /* C=blk 0 thru end */
 103:     0,  0,      /* D=unused */
 104:     33440,  0,      /* E=blk 0 thru 33439 */
 105:     -1, 33440,      /* F=blk 33440 thru end */
 106:     -1, 49324,      /* G=blk 49324 thru end */
 107:     -1, 15884,      /* H=blk 15884 thru end */
 108: }, ra60_sizes[8] = {
 109:     15884,  0,      /* A=sectors 0 thru 15883 */
 110:     33440,  15884,      /* B=sectors 15884 thru 49323 */
 111:     400176, 0,      /* C=sectors 0 thru 400175 */
 112:     82080,  49324,      /* 4.2 G => D=sectors 49324 thru 131403 */
 113:     268772, 131404,     /* 4.2 H => E=sectors 131404 thru 400175 */
 114:     350852, 49324,      /* F=sectors 49324 thru 400175 */
 115:     157570, 242606,     /* UCB G => G=sectors 242606 thru 400175 */
 116:     193282, 49324,      /* UCB H => H=sectors 49324 thru 242605 */
 117: }, ra80_sizes[8] = {
 118:     15884,  0,      /* A=sectors 0 thru 15883 */
 119:     33440,  15884,      /* B=sectors 15884 thru 49323 */
 120:     242606, 0,      /* C=sectors 0 thru 242605 */
 121:     0,  0,      /* D=unused */
 122:     193282, 49324,      /* UCB H => E=sectors 49324 thru 242605 */
 123:     82080,  49324,      /* 4.2 G => F=sectors 49324 thru 131403 */
 124:     192696, 49910,      /* G=sectors 49910 thru 242605 */
 125:     111202, 131404,     /* 4.2 H => H=sectors 131404 thru 242605 */
 126: }, ra81_sizes[8] ={
 127: /*
 128:  * These are the new standard partition sizes for ra81's.
 129:  * An RA_COMPAT system is compiled with D, E, and F corresponding
 130:  * to the 4.2 partitions for G, H, and F respectively.
 131:  */
 132: #ifndef UCBRA
 133:     15884,  0,      /* A=sectors 0 thru 15883 */
 134:     66880,  16422,      /* B=sectors 16422 thru 83301 */
 135:     891072, 0,      /* C=sectors 0 thru 891071 */
 136: #ifdef RA_COMPAT
 137:     82080,  49324,      /* 4.2 G => D=sectors 49324 thru 131403 */
 138:     759668, 131404,     /* 4.2 H => E=sectors 131404 thru 891071 */
 139:     478582, 412490,     /* 4.2 F => F=sectors 412490 thru 891071 */
 140: #else
 141:     15884,  375564,     /* D=sectors 375564 thru 391447 */
 142:     307200, 391986,     /* E=sectors 391986 thru 699185 */
 143:     191352, 699720,     /* F=sectors 699720 thru 891071 */
 144: #endif RA_COMPAT
 145:     515508, 375564,     /* G=sectors 375564 thru 891071 */
 146:     291346, 83538,      /* H=sectors 83538 thru 374883 */
 147: 
 148: /*
 149:  * These partitions correspond to the sizes used by sites at Berkeley,
 150:  * and by those sites that have received copies of the Berkeley driver
 151:  * with deltas 6.2 or greater (11/15/83).
 152:  */
 153: #else UCBRA
 154: 
 155:     15884,  0,      /* A=sectors 0 thru 15883 */
 156:     33440,  15884,      /* B=sectors 15884 thru 49323 */
 157:     891072, 0,      /* C=sectors 0 thru 891071 */
 158:     15884,  242606,     /* D=sectors 242606 thru 258489 */
 159:     307200, 258490,     /* E=sectors 258490 thru 565689 */
 160:     325382, 565690,     /* F=sectors 565690 thru 891071 */
 161:     648466, 242606,     /* G=sectors 242606 thru 891071 */
 162:     193282, 49324,      /* H=sectors 49324 thru 242605 */
 163: 
 164: #endif UCBRA
 165: };
 166: 
 167: struct  ra_info {
 168:     struct  size    *ra_sizes;  /* Partion tables for drive */
 169:     daddr_t     radsize;    /* Max user size form online pkt */
 170:     unsigned    ratype;     /* Drive type int field  */
 171:     unsigned    rastatus;   /* Command status from */
 172:                     /* last onlin or GTUNT */
 173: } ra_info[NRA];
 174: 
 175: 
 176: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
 177: struct  uba_ctlr *udminfo[NUDA];
 178: struct  uba_device *uddinfo[NRA];
 179: struct  uba_device *udip[NUDA][8];      /* 8 == max number of drives */
 180: struct  buf rudbuf[NRA];
 181: struct  buf udutab[NRA];
 182: struct  buf udwtab[NUDA];               /* I/O wait queue, per controller */
 183: 
 184: 
 185: int     udamicro[NUDA];         /* to store microcode level */
 186: int     udaburst[NUDA] = { 0 }; /* DMA burst size, 0 is default */
 187: 
 188: 
 189: /*
 190:  * Controller states
 191:  */
 192: #define S_IDLE  0               /* hasn't been initialized */
 193: #define S_STEP1 1               /* doing step 1 init */
 194: #define S_STEP2 2               /* doing step 2 init */
 195: #define S_STEP3 3               /* doing step 3 init */
 196: #define S_SCHAR 4               /* doing "set controller characteristics" */
 197: #define S_RUN   5               /* running */
 198: 
 199: 
 200: int     udaerror = 0;                   /* causes hex dump of packets */
 201: int     udadebug = 0;
 202: int uda_cp_wait = 0;        /* Something to wait on for command */
 203:                     /* packets and or credits. */
 204: int wakeup();
 205: extern  int hz;         /* Should find the right include */
 206: #ifdef  DEBUG
 207: #define printd  if (udadebug) printf
 208: #define printd10    if(udadebug >= 10) printf
 209: #endif
 210: #define mprintf printf          /* temporary JG hack until Rich fixes*/
 211: 
 212: int     udprobe(), udslave(), udattach(), udintr();
 213: struct  mscp *udgetcp();
 214: 
 215: u_short udstd[] = { 0772150, 0772550, 0777550, 0 };
 216: struct  uba_driver udadriver =
 217:  { udprobe, udslave, udattach, 0, udstd, "ra", uddinfo, "uda", udminfo, 0 };
 218: 
 219: #define b_qsize         b_resid         /* queue size per drive, in udutab */
 220: #define b_ubinfo        b_resid         /* Unibus mapping info, per buffer */
 221: 
 222: udprobe(reg, ctlr)
 223:     caddr_t reg;
 224:     int ctlr;
 225: {
 226:     register int br, cvec;
 227:     register struct uda_softc *sc = &uda_softc[ctlr];
 228:     struct udadevice *udaddr;
 229: 
 230:     int cur_time;
 231: 
 232: #ifdef lint
 233:     br = 0; cvec = br; br = cvec;
 234:     udreset(0); udintr(0);
 235: #endif
 236:     udaddr = (struct udadevice *) reg;
 237: 
 238:     sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4);
 239: #if VAX630
 240:     if (cpu == VAX_630) {
 241:         br = 0x15;
 242:         cvec = sc->sc_ivec;
 243:         return(sizeof (struct udadevice));
 244:     }
 245: #endif
 246:     udaddr->udaip = 0;              /* start initialization */
 247: 
 248:     cur_time = mfpr(TODR);          /* Time of day */
 249:     while(cur_time + TENSEC > mfpr(TODR)){  /* wait for at most 10 secs */
 250:         if((udaddr->udasa & UDA_STEP1) != 0)
 251:             break;
 252:     }
 253:     if(cur_time + TENSEC <= mfpr(TODR))
 254:         return(0);      /* Not a uda or it won't init as it  */
 255:                     /* should within ten seconds.  */
 256:     udaddr->udasa=UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4);
 257:     while((udaddr->udasa&UDA_STEP2)==0)
 258:         DELAY(1000);        /* intr should have */
 259:                     /*   have happened by now */
 260: 
 261:     return(sizeof (struct udadevice));
 262: }
 263: 
 264: /* ARGSUSED */
 265: udslave(ui, reg)
 266:     struct uba_device *ui;
 267:     caddr_t reg;
 268: {
 269:     register struct uba_ctlr *um = udminfo[ui->ui_ctlr];
 270:     register struct uda_softc *sc = &uda_softc[ui->ui_ctlr];
 271:     struct udadevice *udaddr;
 272:     struct  mscp    *mp;
 273:     int i;          /* Something to write into to start */
 274:                     /* the uda polling */
 275: 
 276: 
 277:     udaddr = (struct udadevice *)um->um_addr;
 278:     if(sc->sc_state != S_RUN){
 279:         if(!udinit(ui->ui_ctlr))
 280:             return(0);
 281:     }
 282:     /* Here we will wait for the controller */
 283:     /* to come into the run state or go idle.  If we go idle we are in */
 284:     /* touble and I don't yet know what to do so I will punt */
 285:     while(sc->sc_state != S_RUN && sc->sc_state != S_IDLE); /* spin */
 286:     if(sc->sc_state == S_IDLE){ /* The Uda failed to initialize */
 287:         printf("UDA failed to init\n");
 288:         return(0);
 289:     }
 290:     /* The controller is up so let see if the drive is there! */
 291:     if(0 == (mp = udgetcp(um))){    /* ditto */
 292:         printf("UDA can't get command packet\n");
 293:         return(0);
 294:     }
 295:     mp->mscp_opcode = M_OP_GTUNT;   /* This should give us the drive type*/
 296:     mp->mscp_unit = ui->ui_slave;
 297:     mp->mscp_cmdref = (long) ui->ui_slave;
 298: #ifdef  DEBUG
 299:     printd("uda%d Get unit status slave %d\n",ui->ui_ctlr,ui->ui_slave);
 300: #endif
 301:     ra_info[ui->ui_unit].rastatus = 0;  /* set to zero */
 302:     udip[ui->ui_ctlr][ui->ui_slave] = ui;
 303:     *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT;/* maybe we should poll*/
 304:     i = udaddr->udaip;
 305: #ifdef lint
 306:     i = i;
 307: #endif
 308:     while(!ra_info[ui->ui_unit].rastatus);  /* Wait for some status */
 309:     udip[ui->ui_ctlr][ui->ui_slave] = 0;
 310:     if(!ra_info[ui->ui_unit].ratype)    /* packet from a GTUNT */
 311:         return(0);      /* Failed No such drive */
 312:     else
 313:         return(1);      /* Got it and it is there */
 314: }
 315: 
 316: udattach(ui)
 317:     register struct uba_device *ui;
 318: {
 319:     register struct uba_ctlr *um = ui->ui_mi ;
 320:     struct udadevice *udaddr = (struct udadevice *) um->um_addr;
 321:     struct  mscp    *mp;
 322:     int i;          /* Something to write into to start */
 323:                     /* the uda polling */
 324:     if (ui->ui_dk >= 0)
 325:         dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256);     /* approx */
 326:     ui->ui_flags = 0;
 327:     udip[ui->ui_ctlr][ui->ui_slave] = ui;
 328:     /* check to see if the drive is a available if it is bring it online */
 329:     /* if not then just return.  open will try an online later */
 330:     if(ra_info[ui->ui_unit].rastatus != M_ST_AVLBL)
 331:         return;         /* status was set by a GTUNT */
 332:     if(0 == (mp = udgetcp(um))){    /* ditto */
 333:         printf("UDA can't get command packet\n");
 334:         return;
 335:     }
 336:     mp->mscp_opcode = M_OP_ONLIN;
 337:     mp->mscp_unit = ui->ui_slave;
 338:     mp->mscp_cmdref = (long) ui->ui_slave;
 339: #ifdef  DEBUG
 340:     printd("uda%d ONLIN slave %d\n",ui->ui_ctlr,ui->ui_slave);
 341: #endif
 342:     *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT;
 343:     i = udaddr->udaip;
 344: #ifdef  lint
 345:     i = i;
 346: #endif
 347:     while(ui->ui_flags == 0 && ra_info[ui->ui_unit].ratype != 0);
 348: }
 349: 
 350: /*
 351:  * Open a UDA.  Initialize the device and
 352:  * set the unit online.
 353:  */
 354: /* ARGSUSED */
 355: udopen(dev, flag)
 356:     dev_t dev;
 357:     int flag;
 358: {
 359:     register int unit;
 360:     register struct uba_device *ui;
 361:     register struct uda_softc *sc;
 362:     register struct mscp *mp;
 363:     register struct uba_ctlr *um;
 364:     struct udadevice *udaddr;
 365:     int s,i;
 366: 
 367:     unit = udunit(dev);
 368:     if (unit >= NRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0)
 369:         return (ENXIO);
 370:     sc = &uda_softc[ui->ui_ctlr];
 371:     s = spl5();
 372:     if (sc->sc_state != S_RUN) {
 373:         if (sc->sc_state == S_IDLE)
 374:             if(!udinit(ui->ui_ctlr)){
 375:                 printf("uda: Controller failed to init\n");
 376:                 (void) splx(s);
 377:                 return(ENXIO);
 378:             }
 379:         /* wait for initialization to complete */
 380:         timeout(wakeup,(caddr_t)ui->ui_mi,11*hz);   /* to be sure*/
 381:         sleep((caddr_t)ui->ui_mi, 0);
 382:         if (sc->sc_state != S_RUN)
 383:         {
 384:             (void) splx(s); /* added by Rich */
 385:             return (EIO);
 386:         }
 387:     }
 388:     /* check to see if the device is really there. */
 389:     /* this code was taken from Fred Canters 11 driver */
 390:     um = ui->ui_mi;
 391:     udaddr = (struct udadevice *) um->um_addr;
 392:     (void) splx(s);
 393:     if(ui->ui_flags == 0){
 394:         s = spl5();
 395:         while(0 ==(mp = udgetcp(um))){
 396:             uda_cp_wait++;
 397:             sleep((caddr_t)&uda_cp_wait,PSWP+1);
 398:             uda_cp_wait--;
 399:         }
 400:         mp->mscp_opcode = M_OP_ONLIN;
 401:         mp->mscp_unit = ui->ui_slave;
 402:         mp->mscp_cmdref = (long) & ra_info[ui->ui_unit].ratype;
 403:             /* need to sleep on something */
 404: #ifdef  DEBUG
 405:         printd("uda: bring unit %d online\n",ui->ui_unit);
 406: #endif
 407:         *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT ;
 408:         i = udaddr->udaip;
 409: #ifdef  lint
 410:         i = i;
 411: #endif
 412:         timeout(wakeup,(caddr_t) mp->mscp_cmdref,10 * hz);
 413:             /* make sure we wake up */
 414:         sleep((caddr_t) mp->mscp_cmdref,PSWP+1); /*wakeup in udrsp() */
 415:         (void) splx(s);
 416:     }
 417:     if(ui->ui_flags == 0){
 418:         return(ENXIO);  /* Didn't go online */
 419:     }
 420:     return (0);
 421: }
 422: 
 423: /*
 424:  * Initialize a UDA.  Set up UBA mapping registers,
 425:  * initialize data structures, and start hardware
 426:  * initialization sequence.
 427:  */
 428: udinit(d)
 429:     int d;
 430: {
 431:     register struct uda_softc *sc;
 432:     register struct uda *ud;
 433:     struct udadevice *udaddr;
 434:     struct uba_ctlr *um;
 435: 
 436:     sc = &uda_softc[d];
 437:     um = udminfo[d];
 438:     um->um_tab.b_active++;
 439:     ud = &uda[d];
 440:     udaddr = (struct udadevice *)um->um_addr;
 441:     if (sc->sc_mapped == 0) {
 442:         /*
 443: 		 * Map the communications area and command
 444: 		 * and response packets into Unibus address
 445: 		 * space.
 446: 		 */
 447:         sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)ud,
 448:             sizeof (struct uda), 0);
 449:         sc->sc_uda = (struct uda *)(sc->sc_ubainfo & 0x3ffff);
 450:         sc->sc_mapped = 1;
 451:     }
 452: 
 453:     /*
 454: 	 * Start the hardware initialization sequence.
 455: 	 */
 456: 
 457:     if (udaburst[d] == 0)
 458:         udaburst[d] = UDABURST;
 459:     udaddr->udaip = 0;              /* start initialization */
 460: 
 461:     while((udaddr->udasa & UDA_STEP1) == 0){
 462:         if(udaddr->udasa & UDA_ERR)
 463:             return(0);  /* CHECK */
 464:     }
 465:     udaddr->udasa=UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4);
 466:     /*
 467: 	 * Initialization continues in interrupt routine.
 468: 	 */
 469:     sc->sc_state = S_STEP1;
 470:     sc->sc_credits = 0;
 471:     return(1);
 472: }
 473: 
 474: udstrategy(bp)
 475:     register struct buf *bp;
 476: {
 477:     register struct uba_device *ui;
 478:     register struct uba_ctlr *um;
 479:     register struct buf *dp;
 480:     register int unit;
 481:     register struct size    *rasizes;
 482:     int xunit = minor(bp->b_dev) & 07;
 483:     daddr_t sz, maxsz;
 484:     int s;
 485: 
 486:     sz = (bp->b_bcount+511) >> 9;
 487:     unit = udunit(bp->b_dev);
 488:     if (unit >= NRA) {
 489:         bp->b_error = ENXIO;
 490:         goto bad;
 491:     }
 492:     rasizes = ra_info[unit].ra_sizes;
 493:     ui = uddinfo[unit];
 494:     um = ui->ui_mi;
 495:     if (ui == 0 || ui->ui_alive == 0) {
 496:         bp->b_error = ENXIO;
 497:         goto bad;
 498:     }
 499:     if ((maxsz = rasizes[xunit].nblocks) < 0)
 500:         maxsz = ra_info[unit].radsize - rasizes[xunit].blkoff;
 501:     if (bp->b_blkno < 0 || bp->b_blkno+sz > maxsz ||
 502:         rasizes[xunit].blkoff >= ra_info[unit].radsize) {
 503:         if (bp->b_blkno == maxsz) {
 504:             bp->b_resid = bp->b_bcount;
 505:                 goto done;
 506:         }
 507:         bp->b_error = EINVAL;
 508:         goto bad;
 509:     }
 510:     s = spl5();
 511:     /*
 512: 	 * Link the buffer onto the drive queue
 513: 	 */
 514:     dp = &udutab[ui->ui_unit];
 515:     if (dp->b_actf == 0)
 516:         dp->b_actf = bp;
 517:     else
 518:         dp->b_actl->av_forw = bp;
 519:     dp->b_actl = bp;
 520:     bp->av_forw = 0;
 521:     /*
 522: 	 * Link the drive onto the controller queue
 523: 	 */
 524:     if (dp->b_active == 0) {
 525:         dp->b_forw = NULL;
 526:         if (um->um_tab.b_actf == NULL)
 527:             um->um_tab.b_actf = dp;
 528:         else
 529:             um->um_tab.b_actl->b_forw = dp;
 530:         um->um_tab.b_actl = dp;
 531:         dp->b_active = 1;
 532:     }
 533:     if (um->um_tab.b_active == 0) {
 534: #if defined(VAX750)
 535:         if (cpu == VAX_750
 536:             && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) {
 537:             if (um->um_ubinfo != 0) {
 538:                 printd("udastrat: ubinfo 0x%x\n",um->um_ubinfo);
 539:             } else
 540:                 um->um_ubinfo =
 541:                    uballoc(um->um_ubanum, (caddr_t)0, 0,
 542:                     UBA_NEEDBDP);
 543:         }
 544: #endif
 545:         (void) udstart(um);
 546:     }
 547:     splx(s);
 548:     return;
 549: 
 550: bad:
 551:     bp->b_flags |= B_ERROR;
 552: done:
 553:     iodone(bp);
 554:     return;
 555: }
 556: 
 557: udstart(um)
 558:     register struct uba_ctlr *um;
 559: {
 560:     register struct buf *bp, *dp;
 561:     register struct mscp *mp;
 562:     register struct uda_softc *sc;
 563:     register struct uba_device *ui;
 564:     struct  size    *rasizes;
 565:     struct udadevice *udaddr;
 566:     struct  uda     *ud = &uda[um->um_ctlr];
 567:     int i;
 568: 
 569:     sc = &uda_softc[um->um_ctlr];
 570: 
 571: loop:
 572:     if ((dp = um->um_tab.b_actf) == NULL) {
 573:         /*
 574: 		 * Release uneeded UBA resources and return
 575: 		 */
 576:         um->um_tab.b_active = 0;
 577:         /* Check for response ring transitions lost in the
 578: 		 * Race condition
 579: 		 */
 580:         for (i = sc->sc_lastrsp;; i++) {
 581:             i %= NRSP;
 582:             if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN)
 583:                 break;
 584:             udrsp(um, ud, sc, i);
 585:             ud->uda_ca.ca_rspdsc[i] |= UDA_OWN;
 586:         }
 587:         sc->sc_lastrsp = i;
 588:         return (0);
 589:     }
 590:     if ((bp = dp->b_actf) == NULL) {
 591:         /*
 592: 		 * No more requests for this drive, remove
 593: 		 * from controller queue and look at next drive.
 594: 		 * We know we're at the head of the controller queue.
 595: 		 */
 596:         dp->b_active = 0;
 597:         um->um_tab.b_actf = dp->b_forw;
 598:         goto loop;      /* Need to check for loop */
 599:     }
 600:     um->um_tab.b_active++;
 601:     udaddr = (struct udadevice *)um->um_addr;
 602:     if ((udaddr->udasa&UDA_ERR) || sc->sc_state != S_RUN) {
 603:         harderr(bp, "ra");
 604:         mprintf("Uda%d udasa %o, state %d\n",um->um_ctlr , udaddr->udasa&0xffff, sc->sc_state);
 605:         (void)udinit(um->um_ctlr);
 606:         /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE UDRESET */
 607:         return (0);
 608:     }
 609:     ui = uddinfo[udunit(bp->b_dev)];
 610:     rasizes = ra_info[ui->ui_unit].ra_sizes;
 611:     if (ui->ui_flags == 0) {        /* not online */
 612:         if ((mp = udgetcp(um)) == NULL){
 613:             return (0);
 614:         }
 615:         mp->mscp_opcode = M_OP_ONLIN;
 616:         mp->mscp_unit = ui->ui_slave;
 617:         dp->b_active = 2;
 618:         um->um_tab.b_actf = dp->b_forw; /* remove from controller q */
 619: #ifdef  DEBUG
 620:         printd("uda: bring unit %d online\n", ui->ui_slave);
 621: #endif
 622:         *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
 623:         if (udaddr->udasa&UDA_ERR)
 624:             printf("Uda (%d) Error (%x)\n",um->um_ctlr , udaddr->udasa&0xffff);
 625:         i = udaddr->udaip;
 626:         goto loop;
 627:     }
 628:     switch (cpu) {
 629:     case VAX_8600:
 630:     case VAX_780:
 631:         i = UBA_NEEDBDP|UBA_CANTWAIT;
 632:         break;
 633: 
 634:     case VAX_750:
 635:         i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT;
 636:         break;
 637: 
 638:     case VAX_730:
 639:     case VAX_630:
 640:         i = UBA_CANTWAIT;
 641:         break;
 642:     }
 643:     if ((i = ubasetup(um->um_ubanum, bp, i)) == 0)
 644:         return(1);
 645:     if ((mp = udgetcp(um)) == NULL) {
 646: #if defined(VAX750)
 647:         if (cpu == VAX_750)
 648:             i &= 0xfffffff;         /* mask off bdp */
 649: #endif
 650:         ubarelse(um->um_ubanum,&i);
 651:         return(0);
 652:     }
 653:     mp->mscp_cmdref = (long)bp;     /* pointer to get back */
 654:     mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE;
 655:     mp->mscp_unit = ui->ui_slave;
 656:     mp->mscp_lbn = bp->b_blkno + rasizes[minor(bp->b_dev)&7].blkoff;
 657:     mp->mscp_bytecnt = bp->b_bcount;
 658:     mp->mscp_buffer = (i & 0x3ffff) | (((i>>28)&0xf)<<24);
 659: #if defined(VAX750)
 660:     if (cpu == VAX_750)
 661:         i &= 0xfffffff;         /* mask off bdp */
 662: #endif
 663:     bp->b_ubinfo = i;               /* save mapping info */
 664:     *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
 665:     if (udaddr->udasa&UDA_ERR)
 666:         printf("Uda(%d) udasa (%x)\n",um->um_ctlr , udaddr->udasa&0xffff);
 667:     i = udaddr->udaip;              /* initiate polling */
 668:     dp->b_qsize++;
 669:     if (ui->ui_dk >= 0) {
 670:         dk_busy |= 1<<ui->ui_dk;
 671:         dk_xfer[ui->ui_dk]++;
 672:         dk_wds[ui->ui_dk] += bp->b_bcount>>6;
 673:     }
 674: 
 675:     /*
 676: 	 * Move drive to the end of the controller queue
 677: 	 */
 678:     if (dp->b_forw != NULL) {
 679:         um->um_tab.b_actf = dp->b_forw;
 680:         um->um_tab.b_actl->b_forw = dp;
 681:         um->um_tab.b_actl = dp;
 682:         dp->b_forw = NULL;
 683:     }
 684:     /*
 685: 	 * Move buffer to I/O wait queue
 686: 	 */
 687:     dp->b_actf = bp->av_forw;
 688:     dp = &udwtab[um->um_ctlr];
 689:     bp->av_forw = dp;
 690:     bp->av_back = dp->av_back;
 691:     dp->av_back->av_forw = bp;
 692:     dp->av_back = bp;
 693:     goto loop;
 694: }
 695: 
 696: /*
 697:  * UDA interrupt routine.
 698:  */
 699: udintr(d)
 700:     int d;
 701: {
 702:     register struct uba_ctlr *um = udminfo[d];
 703:     register struct udadevice *udaddr = (struct udadevice *)um->um_addr;
 704:     struct buf *bp;
 705:     register int i;
 706:     register struct uda_softc *sc = &uda_softc[d];
 707:     register struct uda *ud = &uda[d];
 708:     struct uda *uud;
 709:     struct mscp *mp;
 710: 
 711: #ifdef  DEBUG
 712:     printd10("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa);
 713: #endif
 714: #ifdef VAX630
 715:     (void) spl5();
 716: #endif
 717:     switch (sc->sc_state) {
 718:     case S_IDLE:
 719:         printf("uda%d: random interrupt ignored\n", d);
 720:         return;
 721: 
 722:     case S_STEP1:
 723: #define STEP1MASK       0174377
 724: #define STEP1GOOD       (UDA_STEP2|UDA_IE|(NCMDL2<<3)|NRSPL2)
 725:         if ((udaddr->udasa&STEP1MASK) != STEP1GOOD) {
 726:             sc->sc_state = S_IDLE;
 727:             wakeup((caddr_t)um);
 728:             return;
 729:         }
 730:         udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)|
 731:             ((cpu == VAX_780) || (cpu == VAX_8600) ? UDA_PI : 0);
 732:         sc->sc_state = S_STEP2;
 733:         return;
 734: 
 735:     case S_STEP2:
 736: #define STEP2MASK       0174377
 737: #define STEP2GOOD       (UDA_STEP3|UDA_IE|(sc->sc_ivec/4))
 738:         if ((udaddr->udasa&STEP2MASK) != STEP2GOOD) {
 739:             sc->sc_state = S_IDLE;
 740:             wakeup((caddr_t)um);
 741:             return;
 742:         }
 743:         udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)>>16;
 744:         sc->sc_state = S_STEP3;
 745:         return;
 746: 
 747:     case S_STEP3:
 748: #define STEP3MASK       0174000
 749: #define STEP3GOOD       UDA_STEP4
 750:         if ((udaddr->udasa&STEP3MASK) != STEP3GOOD) {
 751:             sc->sc_state = S_IDLE;
 752:             wakeup((caddr_t)um);
 753:             return;
 754:         }
 755:         udamicro[d] = udaddr->udasa;
 756: #ifdef  DEBUG
 757:         printd("Uda%d Version %d model %d\n",d,udamicro[d]&0xF,
 758:             (udamicro[d]>>4) & 0xF);
 759: #endif
 760:         /*
 761: 		 * Requesting the error status (|= 2)
 762: 		 * may hang older controllers.
 763: 		 */
 764:         i = UDA_GO | (udaerror? 2 : 0);
 765:         if (udaburst[d])
 766:             i |= (udaburst[d] - 1) << 2;
 767:         udaddr->udasa = i;
 768:         udaddr->udasa = UDA_GO;
 769:         sc->sc_state = S_SCHAR;
 770: 
 771:         /*
 772: 		 * Initialize the data structures.
 773: 		 */
 774:         uud = sc->sc_uda;
 775:         for (i = 0; i < NRSP; i++) {
 776:             ud->uda_ca.ca_rspdsc[i] = UDA_OWN|UDA_INT|
 777:                 (long)&uud->uda_rsp[i].mscp_cmdref;
 778:             ud->uda_rsp[i].mscp_dscptr = &ud->uda_ca.ca_rspdsc[i];
 779:             ud->uda_rsp[i].mscp_header.uda_msglen = mscp_msglen;
 780:         }
 781:         for (i = 0; i < NCMD; i++) {
 782:             ud->uda_ca.ca_cmddsc[i] = UDA_INT|
 783:                 (long)&uud->uda_cmd[i].mscp_cmdref;
 784:             ud->uda_cmd[i].mscp_dscptr = &ud->uda_ca.ca_cmddsc[i];
 785:             ud->uda_cmd[i].mscp_header.uda_msglen = mscp_msglen;
 786:         }
 787:         bp = &udwtab[d];
 788:         bp->av_forw = bp->av_back = bp;
 789:         sc->sc_lastcmd = 1;
 790:         sc->sc_lastrsp = 0;
 791:         mp = &uda[um->um_ctlr].uda_cmd[0];
 792:         mp->mscp_unit = mp->mscp_modifier = 0;
 793:         mp->mscp_flags = 0;
 794:         mp->mscp_bytecnt = mp->mscp_buffer = 0;
 795:         mp->mscp_errlgfl = mp->mscp_copyspd = 0;
 796:         mp->mscp_opcode = M_OP_STCON;
 797:         mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS;
 798:         *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
 799:         i = udaddr->udaip;      /* initiate polling */
 800:         return;
 801: 
 802:     case S_SCHAR:
 803:     case S_RUN:
 804:         break;
 805: 
 806:     default:
 807:         printf("uda%d: interrupt in unknown state %d ignored\n",
 808:             d, sc->sc_state);
 809:         return;
 810:     }
 811: 
 812:     if (udaddr->udasa&UDA_ERR) {
 813:         printf("uda(%d): fatal error (%o)\n", d, udaddr->udasa&0xffff);
 814:         udaddr->udaip = 0;
 815:         wakeup((caddr_t)um);
 816:     }
 817: 
 818:     /*
 819: 	 * Check for a buffer purge request.
 820: 	 */
 821:     if (ud->uda_ca.ca_bdp) {
 822: #ifdef  DEBUG
 823:         printd("uda: purge bdp %d\n", ud->uda_ca.ca_bdp);
 824: #endif
 825:         UBAPURGE(um->um_hd->uh_uba, ud->uda_ca.ca_bdp);
 826:         ud->uda_ca.ca_bdp = 0;
 827:         udaddr->udasa = 0;      /* signal purge complete */
 828:     }
 829: 
 830:     /*
 831: 	 * Check for response ring transition.
 832: 	 */
 833:     if (ud->uda_ca.ca_rspint) {
 834:         ud->uda_ca.ca_rspint = 0;
 835:         for (i = sc->sc_lastrsp;; i++) {
 836:             i %= NRSP;
 837:             if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN)
 838:                 break;
 839:             udrsp(um, ud, sc, i);
 840:             ud->uda_ca.ca_rspdsc[i] |= UDA_OWN;
 841:         }
 842:         sc->sc_lastrsp = i;
 843:     }
 844: 
 845:     /*
 846: 	 * Check for command ring transition.
 847: 	 */
 848:     if (ud->uda_ca.ca_cmdint) {
 849: #ifdef  DEBUG
 850:         printd("uda: command ring transition\n");
 851: #endif
 852:         ud->uda_ca.ca_cmdint = 0;
 853:     }
 854:     if(uda_cp_wait)
 855:         wakeup((caddr_t)&uda_cp_wait);
 856:     (void) udstart(um);
 857: }
 858: 
 859: /*
 860:  * Process a response packet
 861:  */
 862: udrsp(um, ud, sc, i)
 863:     register struct uba_ctlr *um;
 864:     register struct uda *ud;
 865:     register struct uda_softc *sc;
 866:     int i;
 867: {
 868:     register struct mscp *mp;
 869:     struct uba_device *ui;
 870:     struct buf *dp, *bp,nullbp;
 871:     int st;
 872: 
 873:     mp = &ud->uda_rsp[i];
 874:     mp->mscp_header.uda_msglen = mscp_msglen;
 875:     sc->sc_credits += mp->mscp_header.uda_credits & 0xf;  /* just 4 bits?*/
 876:     if ((mp->mscp_header.uda_credits & 0xf0) > 0x10)    /* Check */
 877:         return;
 878: #ifdef  DEBUG
 879:     printd10("udarsp, opcode 0x%x status 0x%x\n",mp->mscp_opcode,mp->mscp_status);
 880: #endif
 881:     /*
 882: 	 * If it's an error log message (datagram),
 883: 	 * pass it on for more extensive processing.
 884: 	 */
 885:     if ((mp->mscp_header.uda_credits & 0xf0) == 0x10) { /* check */
 886:         uderror(um, (struct mslg *)mp);
 887:         return;
 888:     }
 889:     st = mp->mscp_status&M_ST_MASK;
 890:     /* The controller interrupts as drive 0 */
 891:     /* this means that you must check for controller interrupts */
 892:     /* before you check to see if there is a drive 0 */
 893:     if((M_OP_STCON|M_OP_END) == mp->mscp_opcode){
 894:         if (st == M_ST_SUCC)
 895:             sc->sc_state = S_RUN;
 896:         else
 897:             sc->sc_state = S_IDLE;
 898:         um->um_tab.b_active = 0;
 899:         wakeup((caddr_t)um);
 900:         return;
 901:     }
 902:     if (mp->mscp_unit >= 8)
 903:         return;
 904:     if ((ui = udip[um->um_ctlr][mp->mscp_unit]) == 0)
 905:         return;
 906:     switch (mp->mscp_opcode) {
 907: 
 908:     case M_OP_ONLIN|M_OP_END:
 909:         ra_info[ui->ui_unit].rastatus = st;
 910:         ra_info[ui->ui_unit].ratype =  mp->mscp_mediaid;
 911:         dp = &udutab[ui->ui_unit];
 912:         if (st == M_ST_SUCC) {
 913:             /*
 914: 			 * Link the drive onto the controller queue
 915: 			 */
 916:             dp->b_forw = NULL;
 917:             if (um->um_tab.b_actf == NULL)
 918:                 um->um_tab.b_actf = dp;
 919:             else
 920:                 um->um_tab.b_actl->b_forw = dp;
 921:             um->um_tab.b_actl = dp;
 922:             ui->ui_flags = 1;       /* mark it online */
 923:             ra_info[ui->ui_unit].radsize=(daddr_t)mp->mscp_untsize;
 924: #ifdef  DEBUG
 925:             printd("uda: unit %d online\n", mp->mscp_unit);
 926: #endif
 927: #define F_to_C(x,i)     ( ((x)->mscp_mediaid) >> (i*5+7) & 0x1f ? ( ( (((x)->mscp_mediaid) >>( i*5 + 7)) & 0x1f) + 'A' - 1): ' ')
 928:         /* this mess decodes the Media type identifier */
 929: #ifdef  DEBUG
 930:             printd("uda: unit %d online %x %c%c %c%c%c%d\n"
 931:                 ,mp->mscp_unit, mp->mscp_mediaid
 932:                 ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)
 933:                 ,F_to_C(mp,1),F_to_C(mp,0)
 934:                 ,mp->mscp_mediaid & 0x7f);
 935: #endif
 936:             switch((int)(mp->mscp_mediaid & 0x7f)){
 937:             case    25:
 938:                 ra_info[ui->ui_unit].ra_sizes = ra25_sizes;
 939:                 break;
 940:             case    52:
 941:                 ra_info[ui->ui_unit].ra_sizes = rd52_sizes;
 942:                 break;
 943:             case    53:
 944:                 ra_info[ui->ui_unit].ra_sizes = rd53_sizes;
 945:                 break;
 946:             case    60:
 947:                 ra_info[ui->ui_unit].ra_sizes = ra60_sizes;
 948:                 break;
 949:             case    80:
 950:                 ra_info[ui->ui_unit].ra_sizes = ra80_sizes;
 951:                 break;
 952:             case    81:
 953:                 ra_info[ui->ui_unit].ra_sizes = ra81_sizes;
 954:                 break;
 955:             default:
 956:                 ui->ui_flags = 0;       /* mark it offline */
 957:                 ra_info[ui->ui_unit].ratype = 0;
 958:                 printf("Don't have a parition table for ");
 959:                 printf("a %c%c %c%c%c%d\n"
 960:                 ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)
 961:                 ,F_to_C(mp,1),F_to_C(mp,0)
 962:                 ,mp->mscp_mediaid & 0x7f);
 963:                 while (bp = dp->b_actf) {
 964:                     dp->b_actf = bp->av_forw;
 965:                     bp->b_flags |= B_ERROR;
 966:                     iodone(bp);
 967:                 }
 968:             }
 969:             dp->b_active = 1;
 970:         } else {
 971:             if(dp->b_actf){
 972:                 harderr(dp->b_actf,"ra");
 973:             } else {
 974:                 nullbp.b_blkno = 0;
 975:                 nullbp.b_dev = makedev(UDADEVNUM,ui->ui_unit);
 976:                 harderr(&nullbp, "ra");
 977:             }
 978:             printf("OFFLINE\n");
 979:             while (bp = dp->b_actf) {
 980:                 dp->b_actf = bp->av_forw;
 981:                 bp->b_flags |= B_ERROR;
 982:                 iodone(bp);
 983:             }
 984:         }
 985:         if(mp->mscp_cmdref!=NULL){/* Seems to get lost sometimes */
 986:             wakeup((caddr_t)mp->mscp_cmdref);
 987:         }
 988:         break;
 989: 
 990: /*
 991:  * The AVAILABLE ATTENTION messages occurs when the
 992:  * unit becomes available after spinup,
 993:  * marking the unit offline will force an online command
 994:  * prior to using the unit.
 995:  */
 996:     case M_OP_AVATN:
 997: #ifdef  DEBUG
 998:         printd("uda: unit %d attention\n", mp->mscp_unit);
 999: #endif
1000:         ui->ui_flags = 0;       /* it went offline and we didn't notice */
1001:         ra_info[ui->ui_unit].ratype =  mp->mscp_mediaid;
1002:         break;
1003: 
1004:     case M_OP_END:
1005: /*
1006:  * An endcode without an opcode (0200) is an invalid command.
1007:  * The mscp specification states that this would be a protocol
1008:  * type error, such as illegal opcodes. The mscp spec. also
1009:  * states that parameter error type of invalid commands should
1010:  * return the normal end message for the command. This does not appear
1011:  * to be the case. An invalid logical block number returned an endcode
1012:  * of 0200 instead of the 0241 (read) that was expected.
1013:  */
1014: 
1015:         printf("endcd=%o, stat=%o\n", mp->mscp_opcode, mp->mscp_status);
1016:         break;
1017:     case M_OP_READ|M_OP_END:
1018:     case M_OP_WRITE|M_OP_END:
1019:         bp = (struct buf *)mp->mscp_cmdref;
1020:         ubarelse(um->um_ubanum, (int *)&bp->b_ubinfo);
1021:         /*
1022: 		 * Unlink buffer from I/O wait queue.
1023: 		 */
1024:         bp->av_back->av_forw = bp->av_forw;
1025:         bp->av_forw->av_back = bp->av_back;
1026: #if defined(VAX750)
1027:         if (cpu == VAX_750 && um->um_tab.b_active == 0
1028:             && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) {
1029:             if (um->um_ubinfo == 0)
1030:                 printf("udintr: um_ubinfo == 0\n");
1031:             else
1032:                 ubarelse(um->um_ubanum, &um->um_ubinfo);
1033:         }
1034: #endif
1035:         dp = &udutab[ui->ui_unit];
1036:         dp->b_qsize--;
1037:         if (ui->ui_dk >= 0)
1038:             if (dp->b_qsize == 0)
1039:                 dk_busy &= ~(1<<ui->ui_dk);
1040:         if (st == M_ST_OFFLN || st == M_ST_AVLBL) {
1041:             ui->ui_flags = 0;       /* mark unit offline */
1042:             /*
1043: 			 * Link the buffer onto the front of the drive queue
1044: 			 */
1045:             if ((bp->av_forw = dp->b_actf) == 0)
1046:                 dp->b_actl = bp;
1047:             dp->b_actf = bp;
1048:             /*
1049: 			 * Link the drive onto the controller queue
1050: 			 */
1051:             if (dp->b_active == 0) {
1052:                 dp->b_forw = NULL;
1053:                 if (um->um_tab.b_actf == NULL)
1054:                     um->um_tab.b_actf = dp;
1055:                 else
1056:                     um->um_tab.b_actl->b_forw = dp;
1057:                 um->um_tab.b_actl = dp;
1058:                 dp->b_active = 1;
1059:             }
1060: #if defined(VAX750)
1061:             if (cpu == VAX750 && um->um_ubinfo == 0)
1062:                 um->um_ubinfo =
1063:                    uballoc(um->um_ubanum, (caddr_t)0, 0,
1064:                     UBA_NEEDBDP);
1065: #endif
1066:             return;
1067:         }
1068:         if (st != M_ST_SUCC) {
1069:             harderr(bp, "ra");
1070: #ifdef  DEBUG
1071:             printd("status %o\n", mp->mscp_status);
1072: #endif
1073:             bp->b_flags |= B_ERROR;
1074:         }
1075:         bp->b_resid = bp->b_bcount - mp->mscp_bytecnt;
1076:         iodone(bp);
1077:         break;
1078: 
1079:     case M_OP_GTUNT|M_OP_END:
1080: #ifdef  DEBUG
1081:         printd("GTUNT end packet status = 0x%x media id 0x%x\n"
1082:             ,st,mp->mscp_mediaid);
1083: #endif
1084:         ra_info[ui->ui_unit].rastatus = st;
1085:         ra_info[ui->ui_unit].ratype =  mp->mscp_mediaid;
1086:         break;
1087: 
1088:     default:
1089:         printf("uda: unknown packet\n");
1090:         uderror(um, (struct mslg *)mp);
1091:     }
1092: }
1093: 
1094: 
1095: /*
1096:  * Process an error log message
1097:  *
1098:  * For now, just log the error on the console.
1099:  * Only minimal decoding is done, only "useful"
1100:  * information is printed.  Eventually should
1101:  * send message to an error logger.
1102:  */
1103: uderror(um, mp)
1104:     register struct uba_ctlr *um;
1105:     register struct mslg *mp;
1106: {
1107:     register    i;
1108: 
1109: 
1110:     if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
1111:         printf("uda%d: hard error\n");
1112: 
1113:     mprintf("uda%d: %s error, ", um->um_ctlr,
1114:         mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
1115:     switch (mp->mslg_format) {
1116:     case M_FM_CNTERR:
1117:         mprintf("controller error, event 0%o\n", mp->mslg_event);
1118:         break;
1119: 
1120:     case M_FM_BUSADDR:
1121:         mprintf("host memory access error, event 0%o, addr 0%o\n",
1122:             mp->mslg_event, mp->mslg_busaddr);
1123:         break;
1124: 
1125:     case M_FM_DISKTRN:
1126:         mprintf("disk transfer error, unit %d, grp 0x%x, hdr 0x%x, event 0%o\n",
1127:             mp->mslg_unit, mp->mslg_group, mp->mslg_hdr,
1128: mp->mslg_event);
1129:         break;
1130: 
1131:     case M_FM_SDI:
1132:         mprintf("SDI error, unit %d, event 0%o, hdr 0x%x\n",
1133:             mp->mslg_unit, mp->mslg_event, mp->mslg_hdr);
1134:         for(i = 0; i < 12;i++)
1135:             mprintf("\t0x%x",mp->mslg_sdistat[i] & 0xff);
1136:         mprintf("\n");
1137:         break;
1138: 
1139:     case M_FM_SMLDSK:
1140:         mprintf("small disk error, unit %d, event 0%o, cyl %d\n",
1141:             mp->mslg_unit, mp->mslg_event, mp->mslg_sdecyl);
1142:         break;
1143: 
1144:     default:
1145:         mprintf("unknown error, unit %d, format 0%o, event 0%o\n",
1146:             mp->mslg_unit, mp->mslg_format, mp->mslg_event);
1147:     }
1148: 
1149:     if (udaerror) {
1150:         register long *p = (long *)mp;
1151: 
1152:         for (i = 0; i < mp->mslg_header.uda_msglen; i += sizeof(*p))
1153:             printf("%x ", *p++);
1154:         printf("\n");
1155:     }
1156: }
1157: 
1158: 
1159: /*
1160:  * Find an unused command packet
1161:  */
1162: struct mscp *
1163: udgetcp(um)
1164:     struct uba_ctlr *um;
1165: {
1166:     register struct mscp *mp;
1167:     register struct udaca *cp;
1168:     register struct uda_softc *sc;
1169:     register int i;
1170:     int s;
1171: 
1172:     s = spl5();
1173:     cp = &uda[um->um_ctlr].uda_ca;
1174:     sc = &uda_softc[um->um_ctlr];
1175:     /*
1176: 	 * If no credits, can't issue any commands
1177: 	 * until some outstanding commands complete.
1178: 	 */
1179:     i = sc->sc_lastcmd;
1180:     if(((cp->ca_cmddsc[i]&(UDA_OWN|UDA_INT))==UDA_INT)&&
1181:         (sc->sc_credits >= 2)) {
1182:         sc->sc_credits--;       /* committed to issuing a command */
1183:         cp->ca_cmddsc[i] &= ~UDA_INT;
1184:         mp = &uda[um->um_ctlr].uda_cmd[i];
1185:         mp->mscp_unit = mp->mscp_modifier = 0;
1186:         mp->mscp_opcode = mp->mscp_flags = 0;
1187:         mp->mscp_bytecnt = mp->mscp_buffer = 0;
1188:         mp->mscp_errlgfl = mp->mscp_copyspd = 0;
1189:         sc->sc_lastcmd = (i + 1) % NCMD;
1190:         (void) splx(s);
1191:         return(mp);
1192:     }
1193:     (void) splx(s);
1194:     return(NULL);
1195: }
1196: 
1197: udread(dev, uio)
1198:     dev_t dev;
1199:     struct uio *uio;
1200: {
1201:     register int unit = udunit(dev);
1202: 
1203:     if (unit >= NRA)
1204:         return (ENXIO);
1205:     return (physio(udstrategy, &rudbuf[unit], dev, B_READ, minphys, uio));
1206: }
1207: 
1208: udwrite(dev, uio)
1209:     dev_t dev;
1210:     struct uio *uio;
1211: {
1212:     register int unit = udunit(dev);
1213: 
1214:     if (unit >= NRA)
1215:         return (ENXIO);
1216:     return (physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys, uio));
1217: }
1218: 
1219: udreset(uban)
1220:     int uban;
1221: {
1222:     register struct uba_ctlr *um;
1223:     register struct uba_device *ui;
1224:     register struct buf *bp, *dp;
1225:     register int unit;
1226:     struct buf *nbp;
1227:     int d;
1228: 
1229:     for (d = 0; d < NUDA; d++) {
1230:         if ((um = udminfo[d]) == 0 || um->um_ubanum != uban ||
1231:             um->um_alive == 0)
1232:             continue;
1233:         printf(" uda%d", d);
1234:         um->um_tab.b_active = 0;
1235:         um->um_tab.b_actf = um->um_tab.b_actl = 0;
1236:         uda_softc[d].sc_state = S_IDLE;
1237:         uda_softc[d].sc_mapped = 0; /* Rich */
1238:         for (unit = 0; unit < NRA; unit++) {
1239:             if ((ui = uddinfo[unit]) == 0)
1240:                 continue;
1241:             if (ui->ui_alive == 0 || ui->ui_mi != um)
1242:                 continue;
1243:             udutab[unit].b_active = 0;
1244:             udutab[unit].b_qsize = 0;
1245:         }
1246:         for (bp = udwtab[d].av_forw; bp != &udwtab[d]; bp = nbp) {
1247:             nbp = bp->av_forw;
1248:             bp->b_ubinfo = 0;
1249:             /*
1250: 			 * Link the buffer onto the drive queue
1251: 			 */
1252:             dp = &udutab[udunit(bp->b_dev)];
1253:             if (dp->b_actf == 0)
1254:                 dp->b_actf = bp;
1255:             else
1256:                 dp->b_actl->av_forw = bp;
1257:             dp->b_actl = bp;
1258:             bp->av_forw = 0;
1259:             /*
1260: 			 * Link the drive onto the controller queue
1261: 			 */
1262:             if (dp->b_active == 0) {
1263:                 dp->b_forw = NULL;
1264:                 if (um->um_tab.b_actf == NULL)
1265:                     um->um_tab.b_actf = dp;
1266:                 else
1267:                     um->um_tab.b_actl->b_forw = dp;
1268:                 um->um_tab.b_actl = dp;
1269:                 dp->b_active = 1;
1270:             }
1271:         }
1272:         (void)udinit(d);
1273:     }
1274: }
1275: 
1276: #define DBSIZE 32
1277: 
1278: #define ca_Rspdsc       ca_rspdsc[0]
1279: #define ca_Cmddsc       ca_rspdsc[1]
1280: #define uda_Rsp         uda_rsp[0]
1281: #define uda_Cmd         uda_cmd[0]
1282: 
1283: struct  uda     udad[NUDA];
1284: 
1285: uddump(dev)
1286:     dev_t dev;
1287: {
1288:     struct udadevice *udaddr;
1289:     struct uda *ud_ubaddr;
1290:     char *start;
1291:     int num, blk, unit;
1292:     int maxsz;
1293:     int blkoff;
1294:     register struct uba_regs *uba;
1295:     register struct uba_device *ui;
1296:     register struct uda *udp;
1297:     register struct pte *io;
1298:     register int i;
1299:     struct  size    *rasizes;
1300:     unit = udunit(dev);
1301:     if (unit >= NRA)
1302:         return (ENXIO);
1303: #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
1304:     ui = phys(struct uba_device *, uddinfo[unit]);
1305:     if (ui->ui_alive == 0)
1306:         return (ENXIO);
1307:     uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
1308:     ubainit(uba);
1309:     udaddr = (struct udadevice *)ui->ui_physaddr;
1310:     DELAY(2000000);
1311:     udp = phys(struct uda *, &udad[ui->ui_ctlr]);
1312: 
1313:     num = btoc(sizeof(struct uda)) + 1;
1314:     io = &uba->uba_map[NUBMREG-num];
1315:     for(i = 0; i<num; i++)
1316:         *(int *)io++ = UBAMR_MRV|(btop(udp)+i);
1317:     ud_ubaddr = (struct uda *)(((int)udp & PGOFSET)|((NUBMREG-num)<<9));
1318: 
1319:     udaddr->udaip = 0;
1320:     while ((udaddr->udasa & UDA_STEP1) == 0)
1321:         if(udaddr->udasa & UDA_ERR) return(EFAULT);
1322:     udaddr->udasa = UDA_ERR;
1323:     while ((udaddr->udasa & UDA_STEP2) == 0)
1324:         if(udaddr->udasa & UDA_ERR) return(EFAULT);
1325:     udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
1326:     while ((udaddr->udasa & UDA_STEP3) == 0)
1327:         if(udaddr->udasa & UDA_ERR) return(EFAULT);
1328:     udaddr->udasa = (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
1329:     while ((udaddr->udasa & UDA_STEP4) == 0)
1330:         if(udaddr->udasa & UDA_ERR) return(EFAULT);
1331:     udaddr->udasa = UDA_GO;
1332:     udp->uda_ca.ca_Rspdsc = (long)&ud_ubaddr->uda_Rsp.mscp_cmdref;
1333:     udp->uda_ca.ca_Cmddsc = (long)&ud_ubaddr->uda_Cmd.mscp_cmdref;
1334:     udp->uda_Cmd.mscp_cntflgs = 0;
1335:     udp->uda_Cmd.mscp_version = 0;
1336:     if (udcmd(M_OP_STCON, udp, udaddr) == 0) {
1337:         return(EFAULT);
1338:     }
1339:     udp->uda_Cmd.mscp_unit = ui->ui_slave;
1340:     if (udcmd(M_OP_ONLIN, udp, udaddr) == 0) {
1341:         return(EFAULT);
1342:     }
1343: 
1344:     num = maxfree;
1345:     start = 0;
1346:     rasizes = ra_info[ui->ui_unit].ra_sizes;
1347:     maxsz = rasizes[minor(dev)&07].nblocks;
1348:     blkoff = rasizes[minor(dev)&07].blkoff;
1349:     if(maxsz < 0)
1350:         maxsz = ra_info[unit].radsize-blkoff;
1351:     if (dumplo < 0)
1352:         return (EINVAL);
1353:     if (dumplo + num >= maxsz)
1354:         num = maxsz - dumplo;
1355:     blkoff += dumplo;
1356:     while (num > 0) {
1357:         blk = num > DBSIZE ? DBSIZE : num;
1358:         io = uba->uba_map;
1359:         for (i = 0; i < blk; i++)
1360:             *(int *)io++ = (btop(start)+i) | UBAMR_MRV;
1361:         *(int *)io = 0;
1362:         udp->uda_Cmd.mscp_lbn = btop(start) + blkoff;
1363:         udp->uda_Cmd.mscp_unit = ui->ui_slave;
1364:         udp->uda_Cmd.mscp_bytecnt = blk*NBPG;
1365:         udp->uda_Cmd.mscp_buffer = 0;
1366:         if (udcmd(M_OP_WRITE, udp, udaddr) == 0) {
1367:             return(EIO);
1368:         }
1369:         start += blk*NBPG;
1370:         num -= blk;
1371:     }
1372:     return (0);
1373: }
1374: 
1375: 
1376: udcmd(op, udp, udaddr)
1377:     int op;
1378:     register struct uda *udp;
1379:     struct udadevice *udaddr;
1380: {
1381:     int i;
1382: 
1383:     udp->uda_Cmd.mscp_opcode = op;
1384:     udp->uda_Rsp.mscp_header.uda_msglen = mscp_msglen;
1385:     udp->uda_Cmd.mscp_header.uda_msglen = mscp_msglen;
1386:     udp->uda_ca.ca_Rspdsc |= UDA_OWN|UDA_INT;
1387:     udp->uda_ca.ca_Cmddsc |= UDA_OWN|UDA_INT;
1388:     if (udaddr->udasa&UDA_ERR)
1389:         printf("Udaerror udasa (%x)\n", udaddr->udasa&0xffff);
1390:     i = udaddr->udaip;
1391: #ifdef  lint
1392:     i = i;
1393: #endif
1394:     for (;;) {
1395:         if (udp->uda_ca.ca_cmdint)
1396:             udp->uda_ca.ca_cmdint = 0;
1397:         if (udp->uda_ca.ca_rspint)
1398:             break;
1399:     }
1400:     udp->uda_ca.ca_rspint = 0;
1401:     if (udp->uda_Rsp.mscp_opcode != (op|M_OP_END) ||
1402:         (udp->uda_Rsp.mscp_status&M_ST_MASK) != M_ST_SUCC) {
1403:         printf("error: com %d opc 0x%x stat 0x%x\ndump ",
1404:             op,
1405:             udp->uda_Rsp.mscp_opcode,
1406:             udp->uda_Rsp.mscp_status);
1407:         return(0);
1408:     }
1409:     return(1);
1410: }
1411: 
1412: udsize(dev)
1413:     dev_t dev;
1414: {
1415:     int unit = udunit(dev);
1416:     struct uba_device *ui;
1417:     struct  size    *rasizes;
1418: 
1419:     if (unit >= NRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0
1420:          || ui->ui_flags == 0)
1421:         return (-1);
1422:     rasizes = ra_info[ui->ui_unit].ra_sizes;
1423:     return (rasizes[minor(dev) & 07].nblocks);
1424: }
1425: 
1426: #endif

Defined functions

udattach defined in line 316; used 2 times
udcmd defined in line 1376; used 3 times
uddump defined in line 1285; never used
uderror defined in line 1103; used 2 times
udgetcp defined in line 1162; used 6 times
udinit defined in line 428; used 4 times
udintr defined in line 699; used 3 times
udopen defined in line 355; never used
udprobe defined in line 222; used 2 times
udread defined in line 1197; never used
udreset defined in line 1219; used 1 times
udrsp defined in line 862; used 2 times
udsize defined in line 1412; never used
udslave defined in line 265; used 2 times
udstart defined in line 557; used 2 times
udstrategy defined in line 474; used 2 times
udwrite defined in line 1208; never used

Defined variables

ra25_sizes defined in line 81; used 1 times
ra_info defined in line 173; used 26 times
rudbuf defined in line 180; used 2 times
uda defined in line 73; used 6 times
uda_cp_wait defined in line 202; used 5 times
uda_softc defined in line 68; used 9 times
udaburst defined in line 186; used 4 times
udad defined in line 1283; used 1 times
udadebug defined in line 201; used 2 times
udadriver defined in line 216; used 6 times
udaerror defined in line 200; used 2 times
udamicro defined in line 185; used 3 times
uddinfo defined in line 178; used 7 times
udip defined in line 179; used 4 times
udminfo defined in line 177; used 5 times
udstd defined in line 215; used 1 times
udutab defined in line 181; used 6 times
udwtab defined in line 182; used 8 times

Defined struct's

ra_info defined in line 167; never used
size defined in line 78; used 10 times
uda defined in line 69; used 29 times
uda_softc defined in line 59; used 16 times

Defined macros

DBSIZE defined in line 1276; used 2 times
DEBUG defined in line 18; used 15 times
F_to_C defined in line 927; used 10 times
NCMD defined in line 52; used 3 times
NCMDL2 defined in line 50; used 4 times
NRSP defined in line 51; used 4 times
NRSPL2 defined in line 49; used 4 times
STEP1GOOD defined in line 724; used 1 times
STEP1MASK defined in line 723; used 1 times
STEP2GOOD defined in line 737; used 1 times
STEP2MASK defined in line 736; used 1 times
STEP3GOOD defined in line 749; used 1 times
STEP3MASK defined in line 748; used 1 times
S_IDLE defined in line 192; used 8 times
S_RUN defined in line 197; used 6 times
S_SCHAR defined in line 196; used 1 times
S_STEP1 defined in line 193; used 1 times
S_STEP2 defined in line 194; used 1 times
S_STEP3 defined in line 195; used 1 times
TENSEC defined in line 47; used 2 times
UDABURST defined in line 53; used 1 times
UDADEVNUM defined in line 19; used 1 times
b_qsize defined in line 219; used 4 times
b_ubinfo defined in line 220; used 3 times
ca_Cmddsc defined in line 1279; used 2 times
ca_Rspdsc defined in line 1278; used 2 times
mprintf defined in line 210; used 10 times
phys defined in line 1303; used 3 times
printd defined in line 207; used 13 times
printd10 defined in line 208; used 2 times
uda_Cmd defined in line 1281; used 10 times
uda_Rsp defined in line 1280; used 6 times
udunit defined in line 75; used 8 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3494
Valid CSS Valid XHTML 1.0 Strict